home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / viscobv6.zip / vac22os2 / ibmcobol / samples / toolkit / tcpiptk / socket / selects.c < prev    next >
Text File  |  1996-11-19  |  8KB  |  240 lines

  1. /********************************************************copyrite.xic********/
  2. /*                                                                          */
  3. /*   Licensed Materials - Property of IBM                                   */
  4. /*   IBM TCP/IP for OS/2                                                    */
  5. /*   (C) Copyright IBM Corporation. 1990,1991.                              */
  6. /*                                                                          */
  7. /*   All rights reserved.                                                   */
  8. /*                                                                          */
  9. /*   US Government Users Restricted Rights -                                */
  10. /*   Use, duplication or disclosure restricted by GSA ADP Schedule          */
  11. /*   Contract with IBM Corp.                                                */
  12. /*                                                                          */
  13. /*--------------------------------------------------------------------------*/
  14. /*                                                                          */
  15. /*  DISCLAIMER OF WARRANTIES.  The following [enclosed] code is             */
  16. /*  sample code created by IBM Corporation. This sample code is not         */
  17. /*  part of any standard or IBM product and is provided to you solely       */
  18. /*  for  the purpose of assisting you in the development of your            */
  19. /*  applications.  The code is provided "AS IS", without                    */
  20. /*  warranty of any kind.  IBM shall not be liable for any damages          */
  21. /*  arising out of your use of the sample code, even if they have been      */
  22. /*  advised of the possibility of such damages.                             */
  23. /*--------------------------------------------------------------------------*/
  24. /*
  25.  * Simple TCP and UDP server using BSD select() call.
  26.  */
  27. #ifndef BSD_SELECT
  28. #define BSD_SELECT
  29. #endif
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <memory.h>
  34. #include <types.h>
  35. #include <netinet\in.h>
  36. #include <sys\select.h>       /* contains FD_*** macros */
  37. #include <sys\socket.h>
  38.  
  39. main(int argc, char *argv[])
  40. {
  41.     unsigned short port;           /* port server binds to                  */
  42.     char buf[32];                  /* buffer for sending and receiving data */
  43.     struct sockaddr_in tcp_client; /* client address information            */
  44.     struct sockaddr_in tcp_server; /* server address information            */
  45.     struct sockaddr_in udp_client;
  46.     struct sockaddr_in udp_server;
  47.     int tcpsock,udpsock;           /* socket for accepting connections      */
  48.     int ns;                        /* socket connected to client            */
  49.     int namelen;                   /* length of client name                 */
  50.     int sockint, client_address_size;
  51.     fd_set rdfds;                  /* read set mask for select() call */
  52.     int width=0;                   /* # bits to be checked for select() call */
  53.     int readysock=0;
  54.     struct timeval timeout;
  55.  
  56. /*
  57.  * Check arguments. Should be only one: the port number to bind to.
  58.  */
  59.  
  60.     if (argc != 2)
  61.     {
  62.         fprintf(stderr, "Usage: %s port\n", argv[0]);
  63.         exit(1);
  64.     }
  65.  
  66. /*
  67.  * Initialize with sockets.
  68.  */
  69.     if ((sockint = sock_init()) != 0)
  70.     {
  71.        printf(" INET.SYS probably is not running");
  72.        exit(2);
  73.     }
  74.  
  75. /*
  76.  * First argument should be the port.
  77.  */
  78.     port = (unsigned short) atoi(argv[1]);
  79.  
  80. /*
  81.  *
  82.  * TCP SERVER
  83.  *
  84.  * Get a TCP socket for accepting connections.
  85.  */
  86.     if ((tcpsock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
  87.     {
  88.         psock_errno("Socket()");
  89.         exit(3);
  90.     }
  91.  
  92. /*
  93.  * Bind the TCP socket to the server address.
  94.  */
  95.     tcp_server.sin_family = AF_INET;
  96.     tcp_server.sin_port   = htons(port);
  97.     tcp_server.sin_addr.s_addr = INADDR_ANY;
  98.  
  99.     if (bind(tcpsock, (struct sockaddr *)&tcp_server, sizeof(tcp_server)) < 0)
  100.     {
  101.         psock_errno("Bind()");
  102.         exit(4);
  103.     }
  104.  
  105. /*
  106.  * Listen for connections. Specify the backlog as 5.
  107.  */
  108.     if (listen(tcpsock, 5) != 0)
  109.     {
  110.         psock_errno("Listen()");
  111.         exit(5);
  112.     }
  113.  
  114. /*
  115.  *  UDP SERVER
  116.  *
  117.  * Create a UDP socket in the internet domain and use the
  118.  * default protocol (UDP).
  119.  */
  120.    if ((udpsock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
  121.    {
  122.        psock_errno("socket()");
  123.        exit(6);
  124.    }
  125. /*
  126.  *
  127.  * Bind the UDP socket to the server address.
  128.  *
  129.  */
  130.    udp_server.sin_family      = AF_INET;    /* Server is in Internet Domain */
  131.    udp_server.sin_port        = htons(port);
  132.    udp_server.sin_addr.s_addr = INADDR_ANY; /* Server's Internet Address    */
  133.  
  134.    if (bind(udpsock, (struct sockaddr *)&udp_server, sizeof(udp_server)) < 0)
  135.    {
  136.        psock_errno("bind()");
  137.        exit(7);
  138.    }
  139.  
  140.    for(;;)
  141.       {
  142.         /*
  143.          *  polling every 10 seconds instead of blocking indefinitely.
  144.          */
  145.         timeout.tv_sec = 10l;
  146.         timeout.tv_usec = 0l;
  147.  
  148.         /*
  149.          * read set mask is zeroed before use
  150.          */
  151.         FD_ZERO( &rdfds );
  152.  
  153.         /*
  154.          * add socket discriptor in the read set mask.
  155.          */
  156.         FD_SET( tcpsock, &rdfds );
  157.         if ( tcpsock > width ) width = tcpsock;
  158.         FD_SET( udpsock, &rdfds );
  159.         if ( udpsock > width ) width = udpsock;
  160.  
  161.         /*
  162.          * width can be FD_SETSIZE, i.e. 2048.
  163.          */
  164.         width++;
  165.  
  166.         /*
  167.          * Select() returns the number of socket descriptors selected;
  168.          * if it timed out, then returns 0.
  169.          */
  170.         if ((readysock=select(width, &rdfds, (fd_set *)0, (fd_set *)0, &timeout)) == -1)
  171.          {
  172.            psock_errno("Select()");
  173.            exit(8);
  174.          }
  175.  
  176.         if (readysock > 0)
  177.          {
  178.            /*
  179.             * Check read readiness on the socket.
  180.             */
  181.            if(FD_ISSET(tcpsock,&rdfds))
  182.             {
  183.              /*
  184.               * Accept a connection.
  185.               */
  186.               namelen = sizeof(tcp_client);
  187.               if ((ns = accept(tcpsock, (struct sockaddr *)&tcp_client, &namelen)) == -1)
  188.                {
  189.                   psock_errno("Accept()");
  190.                   exit(9);
  191.                }
  192.  
  193.              /*
  194.               * Receive the message on the newly connected socket.
  195.               */
  196.               if (recv(ns, buf, sizeof(buf), 0) == -1)
  197.                {
  198.                   psock_errno("Recv()");
  199.                   exit(10);
  200.                }
  201.  
  202.              /*
  203.               * Send the message back to the client.
  204.               */
  205.               if (send(ns, buf, sizeof(buf), 0) < 0)
  206.                {
  207.                  psock_errno("Send()");
  208.                  exit(11);
  209.                }
  210.               soclose(ns);
  211.               printf("TCP Server received successfully\n");
  212.             }
  213.            if(FD_ISSET(udpsock,&rdfds))
  214.             {
  215.              /*
  216.               * Receive a message on socket udpsock in buf  of maximum size 32
  217.               * from a client.
  218.               */
  219.               client_address_size = sizeof(udp_client);
  220.  
  221.               if(recvfrom(udpsock, buf, sizeof(buf), 0, (struct sockaddr *) &udp_client,
  222.                           &client_address_size) <0)
  223.                {
  224.                  psock_errno("recvfrom()");
  225.                  exit(12);
  226.                }
  227.              /*
  228.               * Print the message and the name of the client.
  229.               */
  230.               printf("Received message %s from domain %s port %d internet address %s\n",
  231.               buf,
  232.               (udp_client.sin_family == AF_INET?"AF_INET":"UNKNOWN"),
  233.               ntohs(udp_client.sin_port),
  234.               inet_ntoa(udp_client.sin_addr));
  235.            }
  236.          }
  237.       } /* end of for(;;) loop */
  238.  
  239. }
  240.