Chinaunix首页 | 论坛 | 博客
  • 博客访问: 275722
  • 博文数量: 113
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1044
  • 用 户 组: 普通用户
  • 注册时间: 2015-02-15 16:09
文章分类

全部博文(113)

文章存档

2016年(5)

2015年(108)

我的朋友

分类: C/C++

2015-08-26 20:44:18


点击(此处)折叠或打开

  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. #include<string.h>
  9. #define SERVER_PORT 12345
  10. #define TRUE 1
  11. #define FALSE 0
  12. void die(char*mess)
  13. {
  14.     printf("%s\n",mess);exit(1);
  15. }
  16. int main (int argc, char *argv[])
  17. {
  18.    int i, len, rc,on = 1;
  19.    int max_sd, new_sd;
  20.    int desc_ready, end_server = FALSE;
  21.    int close_conn;
  22.    char buffer[80];
  23.    struct sockaddr_in addr;
  24.    struct timeval timeout;
  25.     fd_set master_set, working_set;
  26.     /*************************************************************/
  27.    /* Create an AF_INET stream socket to receive incoming */
  28.    /* connections on */
  29.    /*************************************************************/
  30.   int listen_sd = socket(AF_INET, SOCK_STREAM, 0);
  31.    if (listen_sd < 0)
  32.      die("socket");
  33.    /*************************************************************/
  34.    /* Allow socket descriptor to be reuseable */
  35.    /*************************************************************/
  36.     setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR,(char *)&on, sizeof(on));            
  37.    /*************************************************************/
  38.    /* Set socket to be non-blocking. All of the sockets for */
  39.    /* the incoming connections will also be non-blocking since */
  40.    /* they will inherit that state from the listening socket. */
  41.     /*************************************************************/
  42.     ioctl(listen_sd, FIONBIO, (char *)&on);
  43.    /*************************************************************/
  44.    /* Bind the socket */
  45.    /*************************************************************/
  46.     memset(&addr, 0, sizeof(addr));
  47.     addr.sin_family= AF_INET;
  48.     addr.sin_addr.s_addr = htonl(INADDR_ANY);
  49.     addr.sin_port= htons(SERVER_PORT);
  50.     bind(listen_sd,(struct sockaddr *)&addr, sizeof(addr));
  51.     /*************************************************************/
  52.     /* Set the listen back log */
  53.     /*************************************************************/
  54.     listen(listen_sd, 32);
  55.     /*************************************************************/
  56.     /* Initialize the master fd_set */
  57.    /*************************************************************/
  58.     FD_ZERO(&master_set);
  59.     max_sd = listen_sd;
  60.     FD_SET(listen_sd, &master_set);
  61.    /*************************************************************/
  62.    /* Initialize the timeval struct to 3 minutes. If no */
  63.    /* activity after 3 minutes this program will end. */
  64.    /*************************************************************/
  65.    timeout.tv_sec = 180;
  66.    timeout.tv_usec = 0;

  67.    /*************************************************************/
  68.    /* Loop waiting for incoming connects or for incoming data */
  69.    /* on any of the connected sockets. */
  70.    /*************************************************************/
  71.    do
  72.    {
  73.       /**********************************************************/
  74.       /* Copy the master fd_set over to the working fd_set. */
  75.       /**********************************************************/
  76.       memcpy(&working_set, &master_set, sizeof(master_set));

  77.       /**********************************************************/
  78.       /* Call select() and wait 5 minutes for it to complete. */
  79.       /**********************************************************/
  80.       printf("Waiting on select()...\n");
  81.       rc = select(max_sd + 1, &working_set, NULL, NULL, &timeout);

  82.       /**********************************************************/
  83.       /* Check to see if the select call failed. */
  84.       /**********************************************************/
  85.       if (rc < 0)
  86.       {
  87.          die("select");
  88.          break;
  89.       }
  90.  /**********************************************************/
  91.       /* Check to see if the 5 minute time out expired. */
  92.       /**********************************************************/
  93.       if (rc == 0)
  94.       {
  95.          printf(" select() timed out. End program.\n");
  96.          break;
  97.       }
  98.       /**********************************************************/
  99.       /* One or more descriptors are readable. Need to */
  100.       /* determine which ones they are. */
  101.       /**********************************************************/
  102.       desc_ready = rc;
  103.       for (i=0; i <= max_sd && desc_ready > 0; ++i)
  104.       {
  105.          /*******************************************************/
  106.          /* Check to see if this descriptor is ready */
  107.          /*******************************************************/
  108.          if (FD_ISSET(i, &working_set))
  109.          {
  110.             /****************************************************/
  111.             /* A descriptor was found that was readable - one */
  112.             /* less has to be looked for. This is being done */
  113.             /* so that we can stop looking at the working set */
  114.             /* once we have found all of the descriptors that */
  115.             /* were ready. */
  116.             /****************************************************/
  117.             desc_ready -= 1;

  118.             /****************************************************/
  119.             /* Check to see if this is the listening socket */
  120.             /****************************************************/
  121.             if (i == listen_sd)
  122.             {
  123.                printf(" Listening socket is readable\n");
  124.                /*************************************************/
  125.                /* Accept all incoming connections that are */
  126.                /* queued up on the listening socket before we */
  127.                /* loop back and call select again. */
  128.                /*************************************************/
  129.                do
  130.                {
  131.                   /**********************************************/
  132.                   /* Accept each incoming connection. If */
  133.                   /* accept fails with EWOULDBLOCK, then we */
  134.                   /* have accepted all of them. Any other */
  135.                   /* failure on accept will cause us to end the */
  136.                   /* server. */
  137.                   /**********************************************/
  138.                   new_sd = accept(listen_sd, NULL, NULL);
  139.                   if (new_sd < 0)
  140.                   {
  141.                      if (errno != EWOULDBLOCK)
  142.                      {
  143.                         perror(" accept() failed");
  144.                         end_server = TRUE;
  145.                      }
  146.                      break;
  147.                   }
  148.                  /**********************************************/
  149.                   /* Add the new incoming connection to the */
  150.                   /* master read set */
  151.                   /**********************************************/
  152.                   printf(" New incoming connection - %d\n", new_sd);
  153.                   FD_SET(new_sd, &master_set);
  154.                   if (new_sd > max_sd)
  155.                      max_sd = new_sd;

  156.                   /**********************************************/
  157.                   /* Loop back up and accept another incoming */
  158.                   /* connection */
  159.                   /**********************************************/
  160.                } while (new_sd != -1);
  161.             }

  162.             /****************************************************/
  163.             /* This is not the listening socket, therefore an */
  164.             /* existing connection must be readable */
  165.             /****************************************************/
  166.             else
  167.             {
  168.                printf(" Descriptor %d is readable\n", i);
  169.                close_conn = FALSE;
  170.                /*************************************************/
  171.                /* Receive all incoming data on this socket */
  172.                /* before we loop back and call select again. */
  173.                /*************************************************/
  174.                do
  175.                {
  176.                   /**********************************************/
  177.                   /* Receive data on this connection until the */
  178.                   /* recv fails with EWOULDBLOCK. If any other */
  179.                   /* failure occurs, we will close the */
  180.                   /* connection. */
  181.                   /**********************************************/
  182.                   rc = recv(i, buffer, sizeof(buffer), 0);
  183.                   if (rc < 0)
  184.                   {
  185.                      if (errno != EWOULDBLOCK)
  186.                      {
  187.                         perror(" recv() failed");
  188.                         close_conn = TRUE;
  189.                      }
  190.                      break;
  191.                   }

  192.                   /**********************************************/
  193.                   /* Check to see if the connection has been */
  194.                   /* closed by the client */
  195.                   /**********************************************/
  196.                   if (rc == 0)
  197.                   {
  198.                      printf(" Connection closed\n");
  199.                      close_conn = TRUE;
  200.                      break;
  201.                   }

  202.                   /**********************************************/
  203.                   /* Data was recevied */
  204.                   /**********************************************/
  205.                   len = rc;
  206.                   printf(" %d bytes received\n", len);

  207.                   /**********************************************/
  208.                   /* Echo the data back to the client */
  209.                   /**********************************************/
  210.                   rc = send(i, buffer, len, 0);
  211.                   if (rc < 0)
  212.                   {
  213.                      perror(" send() failed");
  214.                      close_conn = TRUE;
  215.                      break;
  216.                   }

  217.                } while (TRUE);
  218.                  /*************************************************/
  219.                /* If the close_conn flag was turned on, we need */
  220.                /* to clean up this active connection. This */
  221.                /* clean up process includes removing the */
  222.                /* descriptor from the master set and */
  223.                /* determining the new maximum descriptor value */
  224.                /* based on the bits that are still turned on in */
  225.                /* the master set. */
  226.                /*************************************************/
  227.                if (close_conn)
  228.                {
  229.                   close(i);
  230.                   FD_CLR(i, &master_set);
  231.                   if (i == max_sd)
  232.                   {
  233.                      while (FD_ISSET(max_sd, &master_set) == FALSE)
  234.                         max_sd -= 1;
  235.                   }
  236.                }
  237.             } /* End of existing connection is readable */
  238.          } /* End of if (FD_ISSET(i, &working_set)) */
  239.       } /* End of loop through selectable descriptors */

  240.    } while (end_server == FALSE);

  241.    /*************************************************************/
  242.    /* Cleanup all of the sockets that are open */
  243.    /*************************************************************/
  244.    for (i=0; i <= max_sd; ++i)
  245.    {
  246.       if (FD_ISSET(i, &master_set))
  247.          close(i);
  248.    }
  249.    return 0;
  250. }

阅读(1080) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~