zoukankan      html  css  js  c++  java
  • socket中select的使用源码

    下面的代码来自IBM学习网站,是学习socket通信和select使用的一个很好的源码。

    server.c  服务器端

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <sys/ioctl.h>
      4 #include <sys/socket.h>
      5 #include <sys/time.h>
      6 #include <netinet/in.h>
      7 #include <errno.h>
      8 
      9 #define SERVER_PORT  12345
     10 
     11 #define TRUE             1
     12 #define FALSE            0
     13 
     14 main (int argc, char *argv[])
     15 {
     16    int    i, len, rc, on = 1;
     17    int    listen_sd, max_sd, new_sd;
     18    int    desc_ready, end_server = FALSE;
     19    int    close_conn;
     20    char   buffer[80];
     21    struct sockaddr_in   addr;
     22    struct timeval       timeout;
     23    fd_set        master_set, working_set;
     24 
     25    /*************************************************************/
     26    /* Create an AF_INET stream socket to receive incoming       */
     27    /* connections on                                            */
     28    /*************************************************************/
     29    listen_sd = socket(AF_INET, SOCK_STREAM, 0);
     30    if (listen_sd < 0)
     31    {
     32       perror("socket() failed");
     33       exit(-1);
     34    }
     35 
     36    /*************************************************************/
     37    /* Allow socket descriptor to be reuseable                   */
     38    /*************************************************************/
     39    rc = setsockopt(listen_sd, SOL_SOCKET,  SO_REUSEADDR,
     40                    (char *)&on, sizeof(on));
     41    if (rc < 0)
     42    {
     43       perror("setsockopt() failed");
     44       close(listen_sd);
     45       exit(-1);
     46    }
     47 
     48    /*************************************************************/
     49    /* Set socket to be non-blocking.  All of the sockets for    */
     50    /* the incoming connections will also be non-blocking since  */
     51    /* they will inherit that state from the listening socket.   */
     52    /*************************************************************/
     53    rc = ioctl(listen_sd, FIONBIO, (char *)&on);
     54    if (rc < 0)
     55    {
     56       perror("ioctl() failed");
     57       close(listen_sd);
     58       exit(-1);
     59    }
     60 
     61    /*************************************************************/
     62    /* Bind the socket                                           */
     63    /*************************************************************/
     64    memset(&addr, 0, sizeof(addr));
     65    addr.sin_family      = AF_INET;
     66    addr.sin_addr.s_addr = htonl(INADDR_ANY);
     67    addr.sin_port        = htons(SERVER_PORT);
     68    rc = bind(listen_sd,
     69              (struct sockaddr *)&addr, sizeof(addr));
     70    if (rc < 0)
     71    {
     72       perror("bind() failed");
     73       close(listen_sd);
     74       exit(-1);
     75    }
     76 
     77    /*************************************************************/
     78    /* Set the listen back log                                   */
     79    /*************************************************************/
     80    rc = listen(listen_sd, 32);
     81    if (rc < 0)
     82    {
     83       perror("listen() failed");
     84       close(listen_sd);
     85       exit(-1);
     86    }
     87 
     88    /*************************************************************/
     89    /* Initialize the master fd_set                              */
     90    /*************************************************************/
     91    FD_ZERO(&master_set);
     92    max_sd = listen_sd;
     93    FD_SET(listen_sd, &master_set);
     94 
     95    /*************************************************************/
     96    /* Initialize the timeval struct to 3 minutes.  If no        */
     97    /* activity after 3 minutes this program will end.           */
     98    /*************************************************************/
     99    timeout.tv_sec  = 3 * 60;
    100    timeout.tv_usec = 0;
    101 
    102    /*************************************************************/
    103    /* Loop waiting for incoming connects or for incoming data   */
    104    /* on any of the connected sockets.                          */
    105    /*************************************************************/
    106    do
    107    {
    108       /**********************************************************/
    109       /* Copy the master fd_set over to the working fd_set.     */
    110       /**********************************************************/
    111       memcpy(&working_set, &master_set, sizeof(master_set));
    112 
    113       /**********************************************************/
    114       /* Call select() and wait 5 minutes for it to complete.   */
    115       /**********************************************************/
    116       printf("listen_sd is %d ",listen_sd);
    117       printf("Waiting on select()...
    ");
    118      
    119       rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);
    120 
    121       /**********************************************************/
    122       /* Check to see if the select call failed.                */
    123       /**********************************************************/
    124       if (rc < 0)
    125       {
    126          perror("  select() failed");
    127          break;
    128       }
    129 
    130       /**********************************************************/
    131       /* Check to see if the 5 minute time out expired.         */
    132       /**********************************************************/
    133       if (rc == 0)
    134       {
    135          printf("  select() timed out.  End program.
    ");
    136          break;
    137       }
    138 
    139       /**********************************************************/
    140       /* One or more descriptors are readable.  Need to         */
    141       /* determine which ones they are.                         */
    142       /**********************************************************/
    143       desc_ready = rc;
    144       for (i=0; i <= max_sd  &&  desc_ready > 0; ++i)
    145       {
    146          /*******************************************************/
    147          /* Check to see if this descriptor is ready            */
    148          /*******************************************************/
    149          if (FD_ISSET(i, &working_set))
    150          {
    151             /****************************************************/
    152             /* A descriptor was found that was readable - one   */
    153             /* less has to be looked for.  This is being done   */
    154             /* so that we can stop looking at the working set   */
    155             /* once we have found all of the descriptors that   */
    156             /* were ready.                                      */
    157             /****************************************************/
    158             desc_ready -= 1;
    159 
    160             /****************************************************/
    161             /* Check to see if this is the listening socket     */
    162             /****************************************************/
    163             if (i == listen_sd)
    164             {
    165                printf("  Listening socket is readable
    ");
    166                /*************************************************/
    167                /* Accept all incoming connections that are      */
    168                /* queued up on the listening socket before we   */
    169                /* loop back and call select again.              */
    170                /*************************************************/
    171                do
    172                {
    173                   /**********************************************/
    174                   /* Accept each incoming connection.  If       */
    175                   /* accept fails with EWOULDBLOCK, then we     */
    176                   /* have accepted all of them.  Any other      */
    177                   /* failure on accept will cause us to end the */
    178                   /* server.                                    */
    179                   /**********************************************/
    180                   new_sd = accept(listen_sd, NULL, NULL);
    181                   if (new_sd < 0)
    182                   {
    183                      if (errno != EWOULDBLOCK)
    184                      {
    185                         perror("  accept() failed");
    186                         end_server = TRUE;
    187                      }
    188                      break;
    189                   }
    190 
    191                   /**********************************************/
    192                   /* Add the new incoming connection to the     */
    193                   /* master read set                            */
    194                   /**********************************************/
    195                   printf("  New incoming connection - %d
    ", new_sd);
    196                   FD_SET(new_sd, &master_set);
    197                   if (new_sd > max_sd)
    198                      max_sd = new_sd;
    199 
    200                   /**********************************************/
    201                   /* Loop back up and accept another incoming   */
    202                   /* connection                                 */
    203                   /**********************************************/
    204                } while (new_sd != -1);
    205             }
    206 
    207             /****************************************************/
    208             /* This is not the listening socket, therefore an   */
    209             /* existing connection must be readable             */
    210             /****************************************************/
    211             else
    212             {
    213                printf("  Descriptor %d is readable
    ", i);
    214                close_conn = FALSE;
    215                /*************************************************/
    216                /* Receive all incoming data on this socket      */
    217                /* before we loop back and call select again.    */
    218                /*************************************************/
    219                do
    220                {
    221                   /**********************************************/
    222                   /* Receive data on this connection until the  */
    223                   /* recv fails with EWOULDBLOCK.  If any other */
    224                   /* failure occurs, we will close the          */
    225                   /* connection.                                */
    226                   /**********************************************/
    227                   rc = recv(i, buffer, sizeof(buffer), 0);
    228                   if (rc < 0)
    229                   {
    230                      if (errno != EWOULDBLOCK)
    231                      {
    232                         perror("  recv() failed");
    233                         close_conn = TRUE;
    234                      }
    235                      break;
    236                   }
    237 
    238                   /**********************************************/
    239                   /* Check to see if the connection has been    */
    240                   /* closed by the client                       */
    241                   /**********************************************/
    242                   if (rc == 0)
    243                   {
    244                      printf("  Connection closed
    ");
    245                      close_conn = TRUE;
    246                      break;
    247                   }
    248 
    249                   /**********************************************/
    250                   /* Data was recevied                          */
    251                   /**********************************************/
    252                   len = rc;
    253                   printf("  %d bytes received
    ", len);
    254 
    255                   /**********************************************/
    256                   /* Echo the data back to the client           */
    257                   /**********************************************/
    258                   rc = send(i, buffer, len, 0);
    259                   if (rc < 0)
    260                   {
    261                      perror("  send() failed");
    262                      close_conn = TRUE;
    263                      break;
    264                   }
    265 
    266                } while (TRUE);
    267 
    268                /*************************************************/
    269                /* If the close_conn flag was turned on, we need */
    270                /* to clean up this active connection.  This     */
    271                /* clean up process includes removing the        */
    272                /* descriptor from the master set and            */
    273                /* determining the new maximum descriptor value  */
    274                /* based on the bits that are still turned on in */
    275                /* the master set.                               */
    276                /*************************************************/
    277                if (close_conn)
    278                {
    279                   close(i);
    280                   FD_CLR(i, &master_set);
    281                   if (i == max_sd)
    282                   {
    283                      while (FD_ISSET(max_sd, &master_set) == FALSE)
    284                         max_sd -= 1;
    285                   }
    286                }
    287             } /* End of existing connection is readable */
    288          } /* End of if (FD_ISSET(i, &working_set)) */
    289       } /* End of loop through selectable descriptors */
    290 
    291    } while (end_server == FALSE);
    292 
    293    /*************************************************************/
    294    /* Cleanup all of the sockets that are open                  */
    295    /*************************************************************/
    296    for (i=0; i <= max_sd; ++i)
    297    {
    298       if (FD_ISSET(i, &master_set))
    299          close(i);
    300    }
    301 }

    client.c 客户端

     1 /**************************************************************************/
     2 /* Generic client example is used with connection-oriented server designs */
     3 /**************************************************************************/
     4 #include <stdio.h>
     5 #include <stdlib.h>
     6 #include <sys/socket.h>
     7 #include <netinet/in.h>
     8 
     9 #define SERVER_PORT  12345
    10 
    11 main (int argc, char *argv[])
    12 {
    13    int    len, rc;
    14    int    sockfd;
    15    char   send_buf[80];
    16    char   recv_buf[80];
    17    struct sockaddr_in   addr;
    18 
    19    /*************************************************/
    20    /* Create an AF_INET stream socket               */
    21    /*************************************************/
    22    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    23    if (sockfd < 0)
    24    {
    25       perror("socket");
    26       exit(-1);
    27    }
    28 
    29    /*************************************************/
    30    /* Initialize the socket address structure       */
    31    /*************************************************/
    32    memset(&addr, 0, sizeof(addr));
    33    addr.sin_family      = AF_INET;
    34    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    35    addr.sin_port        = htons(SERVER_PORT);
    36 
    37    /*************************************************/
    38    /* Connect to the server                         */
    39    /*************************************************/
    40    rc = connect(sockfd,
    41                 (struct sockaddr *)&addr,
    42                 sizeof(struct sockaddr_in));
    43    if (rc < 0)
    44    {
    45       perror("connect");
    46       close(sockfd);
    47       exit(-1);
    48    }
    49    printf("Connect completed.socketfd is %d .rc is %d 
    ",sockfd,rc);
    50 
    51    /*************************************************/
    52    /* Enter data buffer that is to be sent          */
    53    /*************************************************/
    54    printf("Enter message to be sent:
    ");
    55    gets(send_buf);
    56 
    57    /*************************************************/
    58    /* Send data buffer to the worker job            */
    59    /*************************************************/
    60    len = send(sockfd, send_buf, strlen(send_buf) + 1, 0);
    61    if (len != strlen(send_buf) + 1)
    62    {
    63       perror("send");
    64       close(sockfd);
    65       exit(-1);
    66    }
    67    printf("%d bytes sent
    ", len);
    68 
    69    /*************************************************/
    70    /* Receive data buffer from the worker job       */
    71    /*************************************************/
    72    len = recv(sockfd, recv_buf, sizeof(recv_buf), 0);
    73    if (len != strlen(send_buf) + 1)
    74    {
    75       perror("recv");
    76       close(sockfd);
    77       exit(-1);
    78    }
    79    printf("%d bytes received
    ", len);
    80 
    81    /*************************************************/
    82    /* Close down the socket                         */
    83    /*************************************************/
    84    close(sockfd);
    85 }
  • 相关阅读:
    在TreeView控件节点中显示图片
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1146 Topological Order (25 分)
    PAT 甲级 1145 Hashing
    PAT 甲级 1145 Hashing
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1144 The Missing Number (20 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1151 LCA in a Binary Tree (30 分)
    PAT 甲级 1149 Dangerous Goods Packaging
  • 原文地址:https://www.cnblogs.com/sj-lv/p/3446634.html
Copyright © 2011-2022 走看看