Advertisement
Guest User

Untitled

a guest
Jan 19th, 2020
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.26 KB | None | 0 0
  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <signal.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <sys/wait.h>
  12.  
  13. //głowne zmiany w pliku względem tego w laboratorium to dodanie funkcji odczytującej dane z pliku oraz zmiany w funkcji obsłogującej połączenie
  14. //dowód działania: https://i.imgur.com/EWy4fpe.png
  15.  
  16.  
  17. char * readFileContents(char * filename) //funkcja do odczytania pliku i zapisania go jako pojedynczy wskaźnik char
  18. {
  19.   FILE *f = fopen(filename,"rb");
  20.   if(f == NULL)
  21.   {
  22.     return "Nie znaleziono pliku html. \n";
  23.   }
  24.   fseek(f,0,SEEK_END);
  25.   long fsize = ftell(f);
  26.   fseek(f,0,SEEK_SET);
  27.  
  28.   char * string = malloc(fsize+1);
  29.   fread(string, 1, fsize, f);
  30.   fclose(f);
  31.   string[fsize] = 0;
  32.  
  33.   return string;
  34. }
  35.  
  36. char * ShowTCPAdd( struct sockaddr_in * a )
  37. {
  38.    static char tcpadd [ 16+6 ];
  39.    sprintf( tcpadd, "%s:%d", inet_ntoa( a->sin_addr ), a->sin_port );
  40.    return tcpadd;
  41. }
  42.  
  43. void processConnection( int sock, char * data )
  44. {
  45. //Funkcja do obslugi nawiazanego polaczenia. Wysylamy nagłówek i dane
  46.  
  47.    char * header = "HTTP/1.0 200 OK\nContent-Type: text/html\n\n";
  48.    write(sock,header,strlen(header));   //wysylamy naglowek
  49.    write(sock,data, strlen(data));      //wysylamy dane (naszą strone)
  50. }
  51.  
  52.  
  53. int main( int argc, char * argv [] )
  54. {
  55.    int Sock;
  56.  
  57. //Domyslnie serwer slucha na porcie 13333 i kazdym interfejsie sieciowym
  58.  
  59.    int Server_Port = 13333;
  60.  
  61.    int koniec = 0;
  62.    struct sockaddr_in srvadd;
  63.    struct sockaddr_in kliadd;
  64.  
  65.    printf("You can run this program as follows: %s [portnumber]\n", argv[0] );
  66.  
  67. //Utworzenie gniazda
  68.  
  69.    if( ( Sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0 ) {   // zamiast IPPROTO_TCP 0
  70.       perror( "Can't create socket Sock" );
  71.       return 1;
  72.    }
  73.    printf("Socket created, handle=%d\n", Sock );
  74.  
  75.  
  76. //Jesli podano port na ktorym ma nasluchiwac serwer to bedzie wczytany
  77.  
  78.    if( argc > 1 ) Server_Port = atoi ( argv[ 1 ] );
  79.  
  80. //Przygotowanie struktury przechowujacej adres, na ktory bedzie dowiazany serwer (interfejs i port na ktorym nasluchuje)
  81.  
  82.    memset(&srvadd, 0, sizeof(struct sockaddr_in) );
  83.    srvadd.sin_family = AF_INET;
  84.    srvadd.sin_addr.s_addr = htonl(INADDR_ANY);
  85.    srvadd.sin_port = htons((u_short) Server_Port);
  86.  
  87. //Dowiazanie gniazda
  88.  
  89.    if(bind(Sock, (struct sockaddr*) &srvadd, sizeof(srvadd) ) < 0) {
  90.       perror("Error. Socket not bound.");
  91.       close(Sock);
  92.       return 1;
  93.    }
  94.    printf("Socket is bound.\n");
  95.  
  96.  
  97. //Przjescie w stan oczekiwania na zgloszenia
  98.    char * dataToSend = readFileContents("site.html");
  99.  
  100.    printf( "Listening ...\n" );
  101.    listen( Sock, 2 );
  102.  
  103.    while(! koniec) {
  104.  
  105.       int childPid;
  106.       int childSock;
  107.       int kliaddlen;
  108.  
  109.       kliaddlen = sizeof( kliadd );
  110.  
  111. //Wywolanie funkcji accept, w ktorej proces serwera "zawisa" az do momentu pojawienia sie zadania obslugi (polaczenia od klienta)
  112.  
  113.       childSock = accept( Sock, (struct sockaddr *) &kliadd, &kliaddlen );
  114.  
  115. //Funkcja accept zwraca deskryptor nowego gniazda dedykowanego do obslugi polaczenia (zmienna childSock)
  116.  
  117.       printf( "Server accepted connection from %s\n", ShowTCPAdd( &kliadd ) );
  118.  
  119.       if( childSock < 0 ) {
  120.          printf( "Server main: accept error\n" );
  121.          koniec = 1;
  122.       } else {
  123.  
  124. //Utworzenie procesu potomnego do obslugi polaczenia
  125.  
  126.          childPid = fork();
  127.          if( childPid < 0 ) {
  128.             printf( "Server child: fork error\n" );
  129.             close( childSock );
  130.             koniec = 1;
  131.          }
  132.          if( childPid == 0 ) {
  133.  
  134. //Potomek. Zamyka gniazdo "glowne", na ktorym nasluchuje serwer. Bedzie uzywal gniazda dedykowanego.
  135.  
  136.             close( Sock );
  137.  
  138. //Wejdz do funkcji obslugujacej polaczenie
  139.  
  140.             processConnection( childSock,dataToSend );
  141.             close( childSock );
  142.             printf( "Server child closed connection, exiting\n" );
  143.             exit( 0 );
  144.          } else {
  145.  
  146. //Proces macierzysty. Zamyka gniazdo dedykowane do obslugi polaczenia, po czym wraca w petli do funkcji accept i czeka na kolejne zgloszenia
  147.             close( childSock );
  148.          }
  149.       }
  150.    }
  151.    close( Sock );
  152.    while(wait(0)!=-1){};
  153.    return 0;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement