home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / tcpiptk / socket / selects.c < prev    next >
Text File  |  1999-05-11  |  8KB  |  243 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. #include <sys/time.h>
  39. #include <unistd.h>
  40. #include <arpa/inet.h>
  41.  
  42. main(int argc, char *argv[])
  43. {
  44.     unsigned short port;           /* port server binds to                  */
  45.     char buf[32];                  /* buffer for sending and receiving data */
  46.     struct sockaddr_in tcp_client; /* client address information            */
  47.     struct sockaddr_in tcp_server; /* server address information            */
  48.     struct sockaddr_in udp_client;
  49.     struct sockaddr_in udp_server;
  50.     int tcpsock,udpsock;           /* socket for accepting connections      */
  51.     int ns;                        /* socket connected to client            */
  52.     int namelen;                   /* length of client name                 */
  53.     int sockint, client_address_size;
  54.     fd_set rdfds;                  /* read set mask for select() call */
  55.     int width=0;                   /* # bits to be checked for select() call */
  56.     int readysock=0;
  57.     struct timeval timeout;
  58.  
  59. /*
  60.  * Check arguments. Should be only one: the port number to bind to.
  61.  */
  62.  
  63.     if (argc != 2)
  64.     {
  65.         fprintf(stderr, "Usage: %s port\n", argv[0]);
  66.         exit(1);
  67.     }
  68.  
  69. /*
  70.  * Initialize with sockets.
  71.  */
  72.     if ((sockint = sock_init()) != 0)
  73.     {
  74.        printf(" INET.SYS probably is not running");
  75.        exit(2);
  76.     }
  77.  
  78. /*
  79.  * First argument should be the port.
  80.  */
  81.     port = (unsigned short) atoi(argv[1]);
  82.  
  83. /*
  84.  *
  85.  * TCP SERVER
  86.  *
  87.  * Get a TCP socket for accepting connections.
  88.  */
  89.     if ((tcpsock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
  90.     {
  91.         psock_errno("Socket()");
  92.         exit(3);
  93.     }
  94.  
  95. /*
  96.  * Bind the TCP socket to the server address.
  97.  */
  98.     tcp_server.sin_family = AF_INET;
  99.     tcp_server.sin_port   = htons(port);
  100.     tcp_server.sin_addr.s_addr = INADDR_ANY;
  101.  
  102.     if (bind(tcpsock, (struct sockaddr *)&tcp_server, sizeof(tcp_server)) < 0)
  103.     {
  104.         psock_errno("Bind()");
  105.         exit(4);
  106.     }
  107.  
  108. /*
  109.  * Listen for connections. Specify the backlog as 5.
  110.  */
  111.     if (listen(tcpsock, 5) != 0)
  112.     {
  113.         psock_errno("Listen()");
  114.         exit(5);
  115.     }
  116.  
  117. /*
  118.  *  UDP SERVER
  119.  *
  120.  * Create a UDP socket in the internet domain and use the
  121.  * default protocol (UDP).
  122.  */
  123.    if ((udpsock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
  124.    {
  125.        psock_errno("socket()");
  126.        exit(6);
  127.    }
  128. /*
  129.  *
  130.  * Bind the UDP socket to the server address.
  131.  *
  132.  */
  133.    udp_server.sin_family      = AF_INET;    /* Server is in Internet Domain */
  134.    udp_server.sin_port        = htons(port);
  135.    udp_server.sin_addr.s_addr = INADDR_ANY; /* Server's Internet Address    */
  136.  
  137.    if (bind(udpsock, (struct sockaddr *)&udp_server, sizeof(udp_server)) < 0)
  138.    {
  139.        psock_errno("bind()");
  140.        exit(7);
  141.    }
  142.  
  143.    for(;;)
  144.       {
  145.         /*
  146.          *  polling every 10 seconds instead of blocking indefinitely.
  147.          */
  148.         timeout.tv_sec = 10l;
  149.         timeout.tv_usec = 0l;
  150.  
  151.         /*
  152.          * read set mask is zeroed before use
  153.          */
  154.         FD_ZERO( &rdfds );
  155.  
  156.         /*
  157.          * add socket discriptor in the read set mask.
  158.          */
  159.         FD_SET( tcpsock, &rdfds );
  160.         if ( tcpsock > width ) width = tcpsock;
  161.         FD_SET( udpsock, &rdfds );
  162.         if ( udpsock > width ) width = udpsock;
  163.  
  164.         /*
  165.          * width can be FD_SETSIZE, i.e. 2048.
  166.          */
  167.         width++;
  168.  
  169.         /*
  170.          * Select() returns the number of socket descriptors selected;
  171.          * if it timed out, then returns 0.
  172.          */
  173.         if ((readysock=select(width, &rdfds, (fd_set *)0, (fd_set *)0, &timeout)) == -1)
  174.          {
  175.            psock_errno("Select()");
  176.            exit(8);
  177.          }
  178.  
  179.         if (readysock > 0)
  180.          {
  181.            /*
  182.             * Check read readiness on the socket.
  183.             */
  184.            if(FD_ISSET(tcpsock,&rdfds))
  185.             {
  186.              /*
  187.               * Accept a connection.
  188.               */
  189.               namelen = sizeof(tcp_client);
  190.               if ((ns = accept(tcpsock, (struct sockaddr *)&tcp_client, &namelen)) == -1)
  191.                {
  192.                   psock_errno("Accept()");
  193.                   exit(9);
  194.                }
  195.  
  196.              /*
  197.               * Receive the message on the newly connected socket.
  198.               */
  199.               if (recv(ns, buf, sizeof(buf), 0) == -1)
  200.                {
  201.                   psock_errno("Recv()");
  202.                   exit(10);
  203.                }
  204.  
  205.              /*
  206.               * Send the message back to the client.
  207.               */
  208.               if (send(ns, buf, sizeof(buf), 0) < 0)
  209.                {
  210.                  psock_errno("Send()");
  211.                  exit(11);
  212.                }
  213.               soclose(ns);
  214.               printf("TCP Server received successfully\n");
  215.             }
  216.            if(FD_ISSET(udpsock,&rdfds))
  217.             {
  218.              /*
  219.               * Receive a message on socket udpsock in buf  of maximum size 32
  220.               * from a client.
  221.               */
  222.               client_address_size = sizeof(udp_client);
  223.  
  224.               if(recvfrom(udpsock, buf, sizeof(buf), 0, (struct sockaddr *) &udp_client,
  225.                           &client_address_size) <0)
  226.                {
  227.                  psock_errno("recvfrom()");
  228.                  exit(12);
  229.                }
  230.              /*
  231.               * Print the message and the name of the client.
  232.               */
  233.               printf("Received message %s from domain %s port %d internet address %s\n",
  234.               buf,
  235.               (udp_client.sin_family == AF_INET?"AF_INET":"UNKNOWN"),
  236.               ntohs(udp_client.sin_port),
  237.               inet_ntoa(udp_client.sin_addr));
  238.            }
  239.          }
  240.       } /* end of for(;;) loop */
  241.  
  242. }
  243.