Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <errno.h>
- #include <stdio.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/wait.h>
- char * readFileContents(char * filename)
- {
- FILE *f = fopen(filename,"rb");
- if(f == NULL)
- {
- return "Nie znaleziono pliku html. \n";
- }
- fseek(f,0,SEEK_END);
- long fsize = ftell(f);
- fseek(f,0,SEEK_SET);
- char * string = malloc(fsize+1);
- fread(string, 1, fsize, f);
- fclose(f);
- string[fsize] = 0;
- return string;
- }
- char * ShowTCPAdd( struct sockaddr_in * a )
- {
- static char tcpadd [ 16+6 ];
- sprintf( tcpadd, "%s:%d", inet_ntoa( a->sin_addr ), a->sin_port );
- return tcpadd;
- }
- void processConnection( int sock, char * data )
- {
- //Funkcja do obslugi nawiazanego polaczenia. Tutaj ma mala funkcjonalnosc - tylko odbiera dane i wyswietla na ekranie. Mozna napisac czesc odpowiedzialna za odpowiadanie do klienta uzywajac funkcji write. Serwer moze np zamieniac duze znaki na male i tak poprawiony tekst odsylac do klienta.
- char * header = "HTTP/1.0 200 OK\nContent-Type: text/html\n\n";
- write(sock,header,strlen(header));
- write(sock,data, strlen(data));
- }
- int main( int argc, char * argv [] )
- {
- int Sock;
- //Domyslnie serwer slucha na porcie 13333 i kazdym interfejsie sieciowym
- int Server_Port = 13333;
- int koniec = 0;
- struct sockaddr_in srvadd;
- struct sockaddr_in kliadd;
- printf("You can run this program as follows: %s [portnumber]\n", argv[0] );
- //Utworzenie gniazda
- if( ( Sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0 ) { // zamiast IPPROTO_TCP 0
- perror( "Can't create socket Sock" );
- return 1;
- }
- printf("Socket created, handle=%d\n", Sock );
- //Jesli podano port na ktorym ma nasluchiwac serwer to bedzie wczytany
- if( argc > 1 ) Server_Port = atoi ( argv[ 1 ] );
- //Przygotowanie struktury przechowujacej adres, na ktory bedzie dowiazany serwer (interfejs i port na ktorym nasluchuje)
- memset(&srvadd, 0, sizeof(struct sockaddr_in) );
- srvadd.sin_family = AF_INET;
- srvadd.sin_addr.s_addr = htonl(INADDR_ANY);
- srvadd.sin_port = htons((u_short) Server_Port);
- //Dowiazanie gniazda
- if(bind(Sock, (struct sockaddr*) &srvadd, sizeof(srvadd) ) < 0) {
- perror("Error. Socket not bound.");
- close(Sock);
- return 1;
- }
- printf("Socket is bound.\n");
- //Przjescie w stan oczekiwania na zgloszenia
- char * dataToSend = readFileContents("site.html");
- printf( "Listening ...\n" );
- listen( Sock, 2 );
- while(! koniec) {
- int childPid;
- int childSock;
- int kliaddlen;
- kliaddlen = sizeof( kliadd );
- //Wywolanie funkcji accept, w ktorej proces serwera "zawisa" az do momentu pojawienia sie zadania obslugi (polaczenia od klienta)
- childSock = accept( Sock, (struct sockaddr *) &kliadd, &kliaddlen );
- //Funkcja accept zwraca deskryptor nowego gniazda dedykowanego do obslugi polaczenia (zmienna childSock)
- printf( "Server accepted connection from %s\n", ShowTCPAdd( &kliadd ) );
- if( childSock < 0 ) {
- printf( "Server main: accept error\n" );
- koniec = 1;
- } else {
- //Utworzenie procesu potomnego do obslugi polaczenia
- childPid = fork();
- if( childPid < 0 ) {
- printf( "Server child: fork error\n" );
- close( childSock );
- koniec = 1;
- }
- if( childPid == 0 ) {
- //Potomek. Zamyka gniazdo "glowne", na ktorym nasluchuje serwer. Bedzie uzywal gniazda dedykowanego.
- close( Sock );
- //Wejdz do funkcji obslugujacej polaczenie
- processConnection( childSock,dataToSend );
- close( childSock );
- printf( "Server child closed connection, exiting\n" );
- exit( 0 );
- } else {
- //Proces macierzysty. Zamyka gniazdo dedykowane do obslugi polaczenia, po czym wraca w petli do funkcji accept i czeka na kolejne zgloszenia
- close( childSock );
- }
- }
- }
- close( Sock );
- while(wait(0)!=-1){};
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement