» »

[C] HTTP Server pomoč

[C] HTTP Server pomoč

jizzer ::

Pozdravljeni.

Programiram webserver v C-ju(Linux). Navodilo veleva, da se vsak request izvede v svoji niti, in tu sumim, da se pojavlja problem. In sicer - v Chromiumu se server lepo izvaja, na Firefoxu pa se prvič stran naloži, ampak nato javi Segmentation fault. Nisem ravno vešč C-ja, upravljanja s threadi in upam da mi lahko pomagate.

int main(int argc, char *argv[]){
		
	struct sockaddr_in _serverAddr;
	socklen_t _addrLen = sizeof(_serverAddr);
	int _serverSoc , _clientSoc;
	int s=1;
	
	_serverSoc = socket(AF_INET, SOCK_STREAM, 0);
	if(_serverSoc == -1)
		error("Socket");

	setsockopt(_serverSoc,SOL_SOCKET, SO_REUSEADDR, &s,sizeof(int));
	
	_serverAddr.sin_family = AF_INET;
	_serverAddr.sin_addr.s_addr = INADDR_ANY;
	_serverAddr.sin_port = htons(8080);
	
	if(bind(_serverSoc,(struct sockaddr *)&_serverAddr,sizeof(_serverAddr)) == -1)
		error("Bind");

	
	if(listen(_serverSoc, 100) == -1)
		error("Listen");

	printf("--SERVER STARTED--\n");
	printf("WAITING FOR CONNECTION...\n");
	
	pthread_t request;
	//thread_params.serverAddr = _serverAddr;
	//thread_params.serverSoc = _serverSoc;
	int status;
	while(1){
		_clientSoc = accept(_serverSoc, (struct sockaddr *) &_serverAddr,&_addrLen);
		
		if(_clientSoc == -1)
			error("Connection unsuccessful");
		
		printf("\n***********************************\nConnection successful! Request #%d :",i);
		i++;
		
		status = pthread_create(&request,NULL,*requests,(void*)&_clientSoc);
		
		if(!status)
			pthread_join(request,NULL);

		close(_clientSoc);	
	}
		
	return 0;
}
void *requests(void *parameters){
	
	char buffer2[BUF_SIZE];
	char buffer3[BUF_SIZE];
	char *bufferIMG;
	int * _clientSoc = (int*)parameters;

	read(*_clientSoc, buffer, BUF_SIZE);
	printf("\n - - - - - - - - - - \n%s\n - - - - - - - - - - \n",buffer);
	
	FILE* image;
	fname = getFileName(buffer);
	fextn = getFileExt(fname);
	int gf = getFile(fname);
	fseek(_toSend, 0L, SEEK_END);
	fsize = ftell(_toSend);
	rewind(_toSend);
	printf("\n++++++\nFile: %s\nFile extension: %s\nSize: %d\n++++++\n",fname,fextn,fsize);
	/*if(getFile(fname) == -1){
		strcpy(code, "404 NOT FOUND");
	}else{
		if(!strcmp(fextn,".html")){
			strcpy(ctype,"text/html");
		} else if(!strcmp(fextn,".css")){
			strcpy(ctype,"text/css");
		} else if(!strcmp(fextn,".png")){
			strcpy(ctype,"image/png");
		} else if(!strcmp(fextn,".ico")){
			strcpy(ctype,"image/x-icon");
		}
	}*/
	int read_size,stat;
	/*if(!strcmp(fname,"404.png")){
		printf("Came so far");
		image = fopen("404.png", "rb");
		fseek(image, 0, SEEK_END);
		fsize = ftell(image);
		rewind(image);

		write(*_clientSoc, "HTTP/1.1 200 OK\r\n", 17);
		write(*_clientSoc, "Content-length:", 15);
		write(*_clientSoc, " 226776\r\n", 9);
		write(*_clientSoc, "Content-Type: image/png\r\n\r\n", 27);
		while(!feof(image)){
			read_size = fread(bufferIMG, 1, sizeof(bufferIMG)-1, image);
			do{
					stat = write(*_clientSoc, bufferIMG, read_size);  
			}while (stat < 0);
			bzero(bufferIMG,sizeof(bufferIMG));
		}

		fclose(image);
		}
	else */if(!strcmp(fname,"style.css")){
		printf("FILENAME: %s\nFILE SIZE: %c\n",fname,5);
		fread(buffer3,BUF_SIZE,1,_toSend);
	
		
		write(*_clientSoc,buffer3,sizeof(buffer3)-1);
		//free(buffer3);
	}
	else{
		printf("FILENAME: %s\nFILE SIZE: %c\n",fname,5);
		fread(buffer2,BUF_SIZE,1,_toSend);
		write(*_clientSoc, "HTTP/1.1 200 OK\n", 16);
		//write(*_clientSoc, "HTTP/1.1 404 NOT FOUND\n", 23);
		//write(_clientSoc, "Content-length: 46\n", 19);
		write(*_clientSoc, "Content-Type: text/html\n\n", 25);
		
		write(*_clientSoc,buffer2,sizeof(buffer)-1);
	}	
	//memset(fname,0,sizeof(fname));
	//memset(fextn,0,sizeof(fextn));
	//memset(_toSend,0,sizeof(_toSend));
	
}


Torej zanima me če je implementacija threadov pravilna. Hkrati pa vas prosim, da mi lahko daste še kakšen nasvet za izboljšanje/optimizacijo kode. Rad pozabim tudi na sproščanje memorije, je kje potrebna oz. nepotrebna?

Nasplošno je koda delovala, ampak danes sem hotel še implementirati pošiljanje image fajlov (česar mi tudi nekako ne uspe usposobit, ampak to je vprašanje po tem), pa sem malo zabredel :D Mislil sem da sem že konec danes pa se mi začne dogajati to, pa še rok se mi izteka.

Hvala
  • spremenil: jizzer ()

BigWhale ::

A lahko poves bolj tocno kaj navodilo veleva? Razen tega, da se mora vsak request izvest v svoji niti?

A si mogoce vsaj probal googlat za 'multithreaded socket programming in c'?

Nisem ravno vešč C-ja, upravljanja s threadi in upam da mi lahko pomagate.


Pa če lahko še poveš, česa si sploh vešč.

kunigunda ::

Pod prvo moras vedeti kaj so threadi. Socketa ki ti ga accept vrne ne smes zapreti !!! nosis ga v thread, in ga le-ta zapre ko konca delo.
Join tudi ne delaj, saj potem glavni process nardi connect na thread in caka dokler ga ni konec, tko da na uc, zbrisi tisto po thread create,
pa ne vem kako je v C++, verjetno ga mors se startati.
x=thread.create
x.start

Ostalo ti je pa bigwhale povedu

jizzer ::

BigWhale je izjavil:

A lahko poves bolj tocno kaj navodilo veleva? Razen tega, da se mora vsak request izvest v svoji niti?

Sprogramirati http server. Razen tega, da se mora vsak req izvajati v svoji niti, nič posebnega. Osnovne html fajle, da odpira, pa da ni glih hardcodano.

BigWhale je izjavil:


A si mogoce vsaj probal googlat za 'multithreaded socket programming in c'?

Ne. Hvala lepa za predlog, sem našel kar nekaj uporabnih zadev. Pred tem sem iskal preveč specifično.

BigWhale je izjavil:


Pa če lahko še poveš, česa si sploh vešč.

Nasploh programiranja, ampak pri Cju vem da moreš zelo pazit na memory in prav zaradi tega me zanima če sem kje na kaj pozabil.(ker ponavadi se na to ne oziram)


Pod prvo moras vedeti kaj so threadi. Socketa ki ti ga accept vrne ne smes zapreti !!!

Definicija threada mi je jasna.
Ampak če ga več ne potrebuješ(socketa) ne vidim razloga zakaj ga ne bi?


Join tudi ne delaj, saj potem glavni process nardi connect na thread in caka dokler ga ni konec, tko da na uc, zbrisi tisto po thread create,

Aha, vem kaj misliš, hvala.
Threada ni potrebno štartati posebaj, se zažene z create().

Overall, pa zdaj koda naenkrat dela, brez nekih sprememb ki bi lahko to povzročale, tudi slike pošilja uspešno. Tako da case closed :)
Če pa ima še kdo kakšen nasvet pa je dobrodošel. Hvala

kunigunda ::

jizzer je izjavil:


Definicija threada mi je jasna.
Ampak če ga več ne potrebuješ(socketa) ne vidim razloga zakaj ga ne bi?

Potrebuje ga thread. Ko kreiras thread, mu podas kot parameter se socket s katerim delas.

 
        status = pthread_create(&request,NULL,*requests,(void*)&_clientSoc);
         
        if(!status)
            pthread_join(request,NULL);
 
        close(_clientSoc);  


Ko se thread skreira, istocasno ko gre v izvajanje, se vrne v tvoj glavni program s statusom.
Takoj zatem pa mu zapres socket. Ce ti bo thread dlje casa izvajal operacije nad socketom, bo vmes prislo do exceptionov, saj ga drugje zapres.

socket zapri v glavnem programu, ce thread ni bil uspesno skreiran (if (!status) close(...)), in hkrati po koncanju samega threada v request-u. Join v tem pogoju bo znal pasti, saj ko dobis nazaj status ( >0 je error) thread dejansko ni skreiran in se ne mors joinat nanjga.

Sicer pa ne vem kaj naloga vse zahteva, ampak po kodi sledec to ni web server, zgolj neko simpl hendlanje podatkov po portu :)


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[c] ne sprejme UDP paketa

Oddelek: Programiranje
7999 (587) slovencl
»

[C++] problem z binarnimi datotekami

Oddelek: Programiranje
9963 (828) mallard
»

SMTP v c -ju

Oddelek: Programiranje
282139 (1280) BigWhale
»

Delo z omrezjem v linuxu

Oddelek: Programiranje
101315 (1161) CCfly
»

C: connect() funkcija, kako nastaviti timeout

Oddelek: Programiranje
231807 (1588) fefko-the-bulldog

Več podobnih tem