markizano

socket.c

Jul 30th, 2012
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.93 KB | None | 0 0
  1.  
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <ctype.h>
  7. #include <netdb.h>
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <time.h>
  11. #include <pthread.h>
  12. #include <string.h>
  13. #include <signal.h>
  14. #include <stdlib.h>
  15. #define SUCCESS 0
  16. #define ERROR   1
  17.  
  18. #define SERVER_PORT 1600
  19. #define MAX_MSG 256
  20.  
  21. /* auxillary functions to read newline-terminated strings from a file/socket */
  22. int readnf (int, char *);
  23. int readline(int, char *, int);
  24.  
  25. int server;         /* listening socket descriptor */
  26.  
  27.  
  28. /**
  29.  * cleanup() is called to kill the thread upon SIGINT.
  30. **/
  31. void cleanup() {
  32.     close(server);
  33.     pthread_exit(NULL);
  34.     return;
  35. } /* cleanup() */
  36.  
  37.  
  38. /**
  39.  * Thread handler for incoming connections...
  40. **/
  41. void handler(void * paramsd) {
  42.     struct sockaddr_in cliAddr;
  43.     char line[MAX_MSG];
  44.     char reply[MAX_MSG];
  45.     int i;
  46.     int client_local;   /* keep a local copy of the client's socket descriptor */
  47.     int addr_len;       /* used to store length (size) of sockaddr_in */
  48.     time_t currtime;
  49.     char time_msg1[6] = {'/', 'T', 'I', 'M', 'E', '\n'};
  50.     char time_msg2[6] = {'/', 'T', 'I', 'M', 'E', '\r'};
  51.     char quit_msg1[6] = {'/', 'Q', 'U', 'I', 'T', '\n'};
  52.     char quit_msg2[6] = {'/', 'Q', 'U', 'I', 'T', '\r'};
  53.     char cmd[6];
  54.  
  55.     client_local = *((int *)paramsd); /* store client socket descriptor */
  56.     addr_len = sizeof(cliAddr); /* store value of size of sockaddr_in */
  57.  
  58.     /* get clients name and store in cliAddr */
  59.     getpeername(client_local, (struct sockaddr*)&cliAddr, &addr_len);
  60.     /* reset line */
  61.     memset(line, 0, MAX_MSG);
  62.  
  63.     /* now read lines from the client socket */
  64.     while(readnf(client_local, line) != ERROR) {  /* loop - read from socket */
  65.         if (!strcmp(line,""))   /* string must not be null string */
  66.             break;
  67.  
  68.         for (i = 0; i < 6; i++) {   /* get first 6 chars of string, capitalize */
  69.             cmd[i] = toupper(line[i]);
  70.         }
  71.         /* Did client ask for time? */
  72.         if (strncmp(cmd, time_msg1, 6) == 0 || strncmp(cmd, time_msg2, 6) == 0) {
  73.             printf("Received /TIME from %s:%d\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
  74.             time(&currtime);                  /* get current time */
  75.             strcpy(reply, ctime(&currtime));  /* copy into string */
  76.             send(client_local, reply, strlen(reply), 0); /* return current time to client */
  77.         /* Does client want to quit? */
  78.         } else if (strncmp(cmd, quit_msg1, 6) == 0 || strncmp(cmd, quit_msg2, 6) == 0) {
  79.             printf("Received /QUIT from %s:%d\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
  80.             break;
  81.         } else if (strlen(line) > 2) {
  82.             strcpy(reply, "You:");
  83.             strcat(reply, line);
  84.             send(client_local, reply,strlen(reply),0);
  85.         }
  86.         /* reset line */
  87.         memset(line, 0, MAX_MSG);
  88.     } /* while(readnf) */
  89.  
  90.     shutdown(client_local, SHUT_RD | SHUT_WR);
  91.     close(client_local);
  92.     return;
  93. } /* handler() */
  94.  
  95. /**
  96.  * readnf() - reading from a file descriptor but a bit smarter
  97. **/
  98. int readnf (int fd, char *line) {
  99.     return readline(fd, line, MAX_MSG) < 0? ERROR: SUCCESS;
  100. }
  101.  
  102. /**
  103.  * readline() - read an entire line from a file descriptor until a newline.
  104.  * functions returns the number of characters read but not including the
  105.  * null character.
  106. **/
  107. int readline(int fd, char *str, int maxlen) {
  108.     int n;                              /* number of chars */
  109.     int readcount;                      /* number characters read */
  110.     char c;
  111.  
  112.     for (n = 1; n < maxlen; n++) {      /* read 1 character at a time */
  113.         readcount = read(fd, & c, 1);   /* store result in readcount */
  114.         if (readcount == 1) {           /* 1 char read? */
  115.             * str = c;                  /* copy character to buffer */
  116.             str++;                      /* increment buffer index */
  117.             if (c == '\n')              /* is it a newline character? */
  118.             break;                      /* then exit for loop */
  119.         } else if (readcount == 0) {    /* no character read? */
  120.             if (n == 1) {               /* no character read? */
  121.                 return 0;               /* then return 0 */
  122.             } else {
  123.                 break;                  /* else simply exit loop */
  124.             }
  125.         } else {
  126.             return -1;                  /* error in read() */
  127.         }
  128.     }
  129.  
  130.     *str = 0;                           /* null-terminate the buffer */
  131.     return n;                           /* return number of characters read */
  132. } /* readline() */
  133.  
  134. /* main function */
  135. int main (int argc, char *argv[]) {
  136.     int client;         /* client socket descriptor */
  137.     int addr_len;       /* used to store length (size) of sockaddr_in */
  138.     pthread_t thread;   /* thread variable */
  139.  
  140.     struct sockaddr_in cliAddr;   /* socket address for client */
  141.     struct sockaddr_in servAddr;  /* socket address for server */
  142.  
  143.     signal(SIGINT, cleanup);      /* now handle SIGTERM and SIGINT */
  144.     signal(SIGTERM, cleanup);
  145.  
  146.     /* now create the server socket
  147.        make it an IPV4 socket (PF_INET) and stream socket (TCP)
  148.        and 0 to select default protocol type */
  149.     server = socket(PF_INET, SOCK_STREAM, 0);
  150.     if (server < 0) {
  151.         perror("cannot open socket ");
  152.         return ERROR;
  153.     }
  154.  
  155.     /* now fill in values of the server sockaddr_in struct
  156.        s_addr and sin_port are in Network Byte Order (Big Endian)
  157.        Since Intel CPUs use Host Byte Order (Little Endian), conversion
  158.        is necessary (e.g. htons(), and htonl() */
  159.     servAddr.sin_family = AF_INET;  /* again ipv4 */
  160.     servAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* local address */
  161.     servAddr.sin_port = htons(SERVER_PORT);
  162.     memset(servAddr.sin_zero, 0, 8);
  163.  
  164.     /* now bind server port
  165.        associate socket (server) with IP address:port (servAddr) */
  166.     if (bind(server, (struct sockaddr *) &servAddr, sizeof(struct sockaddr)) < 0) {
  167.         perror("cannot bind port ");
  168.         return ERROR;
  169.     }
  170.  
  171.     /* wait for connection from client with a pending queue of size 5 */
  172.     listen(server, 5);
  173.  
  174.     while(1) { /* infinite loop */
  175.         printf("%s: waiting for data on port TCP %u\n", argv[0], SERVER_PORT);
  176.         addr_len = sizeof(cliAddr);
  177.  
  178.         /* new socket for client connection
  179.            accept() will block until a connection is present
  180.            accept will return a NEW socket for the incoming connection
  181.            server socket will continue listening
  182.            store client address in cliAddr */
  183.         client = accept(server, (struct sockaddr *) &cliAddr, &addr_len);
  184.         if (client < 0) {
  185.             perror("cannot accept connection ");
  186.             break;
  187.         }
  188.         pthread_create(&thread, 0, (void*)&handler, (void*) &client);
  189.     } /* while (1) */
  190.  
  191.     close(server);
  192.     exit(0);
  193. } /* main() */
Advertisement
Add Comment
Please, Sign In to add comment