home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_09_09 / 9n09048a < prev    next >
Text File  |  1991-07-17  |  6KB  |  151 lines

  1. Listing 1. The stream sockets example. Server program.
  2.  
  3. /* receive -- the server program. It runs in the background listening for
  4.  * client connections. Remote or local clients send character strings to the 
  5.  * server that receives them and echoes them on the server side. The present
  6.  * program operates in conjunction with one or more client programs called
  7.  * "send". 
  8.  *        Usage:  receive &
  9.  */
  10.  
  11. #include   <sys/types.h>
  12. #include   <sys/socket.h>
  13. #include   <netdb.h>
  14. #include   <netinet/in.h>
  15.  
  16. #define    FAIL   1                  /* exit code in case of failure */
  17. #define    SUCC   0                  /* correct termination code     */
  18. #define    PORT_NUMBER  2227         /* arbitrarily chosen port number for 
  19.                                       * client-server communication. Must be
  20.                                       * non-reserved (> 1023) and the same in 
  21.                                       * client and server 
  22.                                       */
  23. #define    MAX_CONN  5               /* maximum number of connection requests
  24.                                       * that can be queued.
  25.                                       */
  26.  
  27. int sock_descr ;                     /* listen socket descriptor       */
  28. int new_sockds ;                     /* connected socket descriptor    */
  29. struct sockaddr_in client_addr ;     /* peer socket address            */ 
  30.  
  31. /* ------------------------------------------------------------------- */
  32.  
  33. main()
  34. {
  35.     void error(), server() ;
  36.     struct sockaddr_in my_sock_addr ;    /* local socket address structure */ 
  37.     int length = sizeof(struct sockaddr) ;
  38.  
  39.     /* create the listen socket */
  40.     if ((sock_descr = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  41.         error("error opening stream socket in server", "") ;
  42.  
  43.     /* fill socket data structure */
  44.     my_sock_addr.sin_family        = AF_INET ;
  45.     my_sock_addr.sin_addr.s_addr   = INADDR_ANY ;
  46.     my_sock_addr.sin_port          = PORT_NUMBER ; 
  47.  
  48.     /* bind the listen address to the socket */ 
  49.     if (bind(sock_descr, (struct sockaddr *)&my_sock_addr, length) != 0)
  50.         error("error binding to stream socket", "") ;
  51.     
  52.     /* start listening at the socket for incoming connections. A maximum
  53.      * of MAX_CONN pending connections is allowed. 
  54.      */
  55.     if (listen(sock_descr, MAX_CONN) != 0)
  56.         error("error in listen() call", "") ;
  57.     for ( ; ; )  {
  58.  
  59.         /* the following "accept" call will block until a connection
  60.          * request arrives. When it is done, it returns a new socket
  61.          * descriptor through which client and server can communicate.
  62.          * The original socket "sock_descr" is kept for listening to
  63.          * further connection requests.
  64.          */ 
  65.  
  66.         if ((new_sockds = accept(sock_descr, (struct sockaddr *)&client_addr, 
  67.                                  &length)) == -1)
  68.             error("accept", "") ;
  69.         /* create new process to handle client requests */
  70.         switch ( fork() )  {
  71.             case -1  :  
  72.                 error("fork: can't create new process", "") ;
  73.             case  0  :  /* child, communicates with client */
  74.                 server() ;
  75.                 exit(SUCC) ;
  76.             default  :  /* parent */
  77.                 /* original process don't need to keep transmission socket */
  78.                 if (close(new_sockds) == -1)
  79.                     error("father, close communication socket", "") ;
  80.                 putchar('\n') ;
  81.                 /* and keep looping waiting for further connection requests */
  82.         }
  83.     } 
  84. }
  85.  
  86. /* ------------------------------------------------------------------- */
  87.  
  88. /* server -- the routine that actually serves incoming client requests */
  89.  
  90. void server()
  91. {
  92.     char *inet_ntoa(); /* returns a pointer to a 'dot' notation Internet addr.*/
  93.     char client_name[50], *p = client_name ;
  94.     struct hostent *client_info, *gethostbyaddr() ;
  95.     char buffer[256] ;      /* buffer to read incoming strings */
  96.     int nread ;
  97.     char message[12] ;      /* termination message for client  */
  98.  
  99.     (void)strcpy(message, "-- ALL DONE") ;
  100.     /* close the listen socket inherited from the father */        
  101.     if (close(sock_descr) == -1)
  102.         error("child: close listen socket", "") ;
  103.  
  104.     /* find out and write client information given the client address 
  105.      * structure 'client_addr' returned in the preceding 'accept' call.
  106.      */ 
  107.     if ((client_info = gethostbyaddr((char *)&client_addr.sin_addr,
  108.               sizeof(struct in_addr), client_addr.sin_family)) == NULL)  {
  109.  
  110.         /* since the information is unavailable, use the ascii dot format
  111.          * of the Internet address. 
  112.          */
  113.         (void)strcpy(client_name, "Unknown Host") ;
  114.         (void)strcat(client_name, " ") ;
  115.         (void)strcat(client_name, inet_ntoa(client_addr.sin_addr)) ;
  116.     }
  117.     else
  118.         p = client_info->h_name ;         
  119.     printf("'send' process on host '%s' connected to 'receive' server\n", p) ;
  120.  
  121.     /* start receiving requests from the client process */ 
  122.     while ((nread = read(new_sockds, buffer, sizeof buffer)) > 0)
  123.         printf("server received: '%s'\n", buffer) ;
  124.     if (nread < 0)
  125.         error("socket read error", "") ;
  126.     /* the server is finished handling client requests, send termination
  127.      * message to the client.
  128.      */
  129.     if (write(new_sockds, message, sizeof message) < 0)
  130.         error("server write error", "") ;
  131.     if (close(new_sockds) == -1)
  132.         error("close socket", "") ;
  133. }
  134.  
  135. /* ------------------------------------------------------------------- */
  136.  
  137. void error(s1, s2)   /* print system call error message and exit */
  138.     char *s1, *s2 ;
  139. {
  140.     extern int errno, sys_nerr ;
  141.     extern char *sys_errlist[] ;
  142.  
  143.     fprintf(stderr, "%s %s", s1, s2) ;
  144.     if (errno > 0 && errno < sys_nerr)
  145.         fprintf(stderr, " (%s)", sys_errlist[errno]) ;
  146.     fprintf(stderr, "\n") ;
  147.     exit(FAIL) ;
  148. }
  149.  
  150. /* ------------------------------------------------------------------- */ 
  151.