• 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 }
  • 相关阅读:
    电商工具 谷歌插件 版本 2021-03-04
    PowerDesigner 自定义脚本
    MapReduce案例之寻找共同好友
    Hadoop之MapReduce开发总结
    python之文件操作
    python字典、集合
    python元组
    python列表练习
    python之列表
    python之编码解码、字符串常用方法
  • 原文地址:https://www.cnblogs.com/sj-lv/p/3446634.html
Copyright © 2020-2023  润新知