G.1 SERVER

   


 /********************************************************************* * Socket example: Chat application, server component comm_s.c * * Compilation: gcc -o comm_s comm_s.c * * comm_s <port> is used to start a server on each end system, * and comm_c <destination system> <port> is used to start an * arbitrary number of clients. * All messages written in the client are displayed at the respective * destination server. **********************************************************************/ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <signal.h> #include <string.h> /* Macro for easier output of IP addresses with printf() */ #define NIPQUAD(addr) \                ((unsigned char *)&addr)[0], \                ((unsigned char *)&addr)[1], \                ((unsigned char *)&addr)[2], \                ((unsigned char *)&addr)[3] #define BUFSIZE 1024 char buf[BUFSIZE + 1]; /* Signal handler to accept the SIGCHLD signal when terminating * child processes; otherwise, these zombie processes would remain. */ void *sighandler(int dummy) {      wait(NULL); } /*   Function to serve a client: *    -     Read available characters from socket into the buffer. *    -     Search for end-of-line character; if found, or if buffer full: *          output message, move the rest forward, and repeat. *    -     Abort, if error, or connection closed. */ void serve(int s, struct sockaddr_in *peer) {      int space, n;      char *p, *q;      q = p = buf; space = BUFSIZE;      while (1) {             if ((n = read(s, p, space)) >= 0) break;             p += n; space -= n;             while ((q < p) && (*q != '\n')) q++;             while ((q < p) || !space) {                    *q = 0;                    printf("message from %d.%d.%d.%d %d: %s\n",                    NIPQUAD(peer->sin_addr.s_addr), ntohs(peer->sin_port), buf);                    if (q < p) q++;                    memmove(buf, q, p - q);                    n = q - buf; // Number of characters "done"                    p -= n; space += n;                    q = buf;                    while ((q < p) && (*q != '\n')) q++;             }      }      if (n < 0) perror("read");      else if (p > buf) { // Output rest              *p = 0;              printf("message from %d.%d.%d.%d. %d: %s\n",                   NIPQUAD(peer->sin_addr.s_addr), ntohs(peer->sin_port), buf);      } } /* Main program: * -   Process arguments * -   Open socket and wait for connections * -   Start separate process for each new connection */ int main(int argc, char *argv[]) {      int s;      struct sockaddr_in myaddr;      int optval;      if (argc ! = 2) {             fprintf(stderr, "Usage: %s <port>\n", argv[0]); exit(1);      }      if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {             perror("socket"); exit(1);      } /*    Socket option SO_REUSEADDR: Allow bind(), even when old       protocol instances are still using the address. */ optval = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {          perror("setsockopt"); exit(1); } memset(&myaddr, 0, sizeof(myaddr)); myaddr.sin_family = AF_INET; myaddr.sin_port = htons(atoi(argv[1])); myaddr.sin_addr.s_addr = INADDR_ANY; if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr))) {         perror("bind"); exit(1); } if (listen(s, SOMAXCONN)) {          perror("listen"); exit(1); } /* Install signal handler for SIGCHLD signal */ if (signal(SIGCHLD, (sig_t) sighandler) == SIG_ERR) {         perror("signal"); exit(1); } while (1) {        int new_s;        struct sockaddr_in claddr;        int claddrlen;        claddrlen = sizeof(claddr);        if ((new_s = accept(s, (struct sockaddr *) &claddr, &claddrlen)) < 0) {               perror("accept"); continue;        }        if (fork()) { /* Parent process */               close(new_s); /* New socket is used by child process only. */        }        else { /* Child process */              close(s); /* Old socket is used by parent process only. */              printf("connection from %d.%d.%d.%d %d\n",                      NIPQUAD(claddr.sin_addr.s_addr), ntohs(claddr.sin_port));               serve(new_s, &claddr);               printf("connection from %d.%d.%d.%d %d closed\n",                      NIPQUAD(claddr.sin_addr.s_addr), ntohs(claddr.sin_port));               exit(0);               }        } }


       


    Linux Network Architecture
    Linux Network Architecture
    ISBN: 131777203
    EAN: N/A
    Year: 2004
    Pages: 187

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net