socket通信之完整的多路复用

前一篇文章是介绍的select一个极为简单的用法,这篇将select和socket结合使用,完成单线程多用户连接,用户退出后,可用连接自动+1,。

客户端同http://blog.csdn.net/xluren/article/details/8043484 中的客户端

服务器端代码如下:

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <errno.h>  
  5. #include <string.h>  
  6. #include <sys/types.h>  
  7. #include <sys/socket.h>  
  8. #include <netinet/in.h>  
  9. #include <arpa/inet.h>  
  10.   
  11. #define MYPORT 6666    // the port users will be connecting to  
  12.   
  13. #define BACKLOG 5     // how many pending connections queue will hold  
  14.   
  15. #define BUF_SIZE 1024  
  16. #define MAXCLIENT 5  
  17. int fd_access[BACKLOG];    // accepted connection fd  
  18. int conn_amount;    // current connection amount  
  19.   
  20. void showclient()  
  21. {  
  22.         int i;  
  23.         printf("client amount: %d\n", conn_amount);  
  24.         printf("\n");  
  25. }  
  26.   
  27. int main(void)  
  28. {  
  29.         int sock_fd, new_fd;  // listen on sock_fd, new connection on new_fd  
  30.         struct sockaddr_in server_addr;    // server address information  
  31.         struct sockaddr_in client_addr; // connector's address information  
  32.         socklen_t sin_size;  
  33.         char buf[BUF_SIZE];  
  34.         int ret;  
  35.         int i;  
  36.   
  37.         if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)   
  38.         {  
  39.                 perror("socket");  
  40.                 exit(1);  
  41.         }   
  42.         server_addr.sin_family = AF_INET;         // host byte order  
  43.         server_addr.sin_port = htons(MYPORT);     // short, network byte order  
  44.         server_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP  
  45.         memset(server_addr.sin_zero, '\0'sizeof(server_addr.sin_zero));  
  46.         if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)   
  47.         {  
  48.                 perror("bind");  
  49.                 exit(1);  
  50.         }  
  51.         if (listen(sock_fd, BACKLOG) == -1)   
  52.         {  
  53.                 perror("listen");  
  54.                 exit(1);  
  55.         }  
  56.         printf("listen port %d\n", MYPORT);  
  57.   
  58.         fd_set fdsr;  
  59.         int maxsock;  
  60.         struct timeval tv;  
  61.   
  62.         conn_amount = 0;  
  63.         sin_size = sizeof(client_addr);  
  64.         maxsock = MAXCLIENT;  
  65.         FD_ZERO(&fdsr);  
  66.         while (1)   
  67.         {  
  68.                 FD_SET(sock_fd, &fdsr);  
  69.   
  70.                 tv.tv_sec = 3;  
  71.                 tv.tv_usec = 0;  
  72.   
  73.                 for (i = 0; i < BACKLOG; i++)   
  74.                 {  
  75.                         printf("fd---%d\n",fd_access[i]);  
  76.                         if (fd_access[i] != 0)  
  77.                         {  
  78.                                 FD_SET(fd_access[i], &fdsr);  
  79.                         }  
  80.                 }  
  81.   
  82.                 ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);  
  83.                 if (ret < 0)   
  84.                 {  
  85.                         perror("select");  
  86.                         break;  
  87.                 }   
  88.                 else if (ret == 0)   
  89.                 {  
  90.                         printf("timeout\n");  
  91.                         continue;  
  92.                 }  
  93.                 printf("select----ret%d",ret);  
  94.                 // check every fd in the set  
  95.                 for (i = 0; i < MAXCLIENT; i++)   
  96.                 {  
  97.                         if (FD_ISSET(fd_access[i], &fdsr))   
  98.                         {  
  99.                                 ret = recv(fd_access[i], buf, sizeof(buf), 0);  
  100.                                 if (ret <= 0)   
  101.                                 {  
  102.                                         printf("client[%d] close\n", i);  
  103.                                         close(fd_access[i]);  
  104.                                         FD_CLR(fd_access[i], &fdsr);  
  105.                                         fd_access[i] = 0;  
  106.                                         conn_amount--;  
  107.                                 }   
  108.                                 else   
  109.                                 {  
  110.                                         if (ret < BUF_SIZE)  
  111.                                                 memset(&buf[ret], '\0', 1);                      
  112.                                         printf("client[%d] send:%s\n", i, buf);  
  113.                                 }  
  114.                         }  
  115.                 }  
  116.                 // check whether a new connection comes  
  117.                 if (FD_ISSET(sock_fd, &fdsr))   
  118.                 {  
  119.                         new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);  
  120.                         if (new_fd <= 0)   
  121.                         {  
  122.                                 perror("accept");  
  123.                                 continue;  
  124.                         }  
  125.                         // add to fd queue  
  126.                         if (conn_amount < BACKLOG)   
  127.                         {  
  128.                                 for(i = 0;i < MAXCLIENT;i++)  
  129.                                 {  
  130.                                         if(fd_access[i] == 0)  
  131.                                         {  
  132.                                                 fd_access[i] = new_fd;  
  133.                                                 break;  
  134.                                         }  
  135.   
  136.                                 }//for  
  137.                                 conn_amount++;  
  138.                                 printf("new connection client[%d] %s:%d\n",   
  139.                                 conn_amount,inet_ntoa(client_addr.sin_addr),   
  140.                                 ntohs(client_addr.sin_port));  
  141.                                 if (new_fd > maxsock)  
  142.                                         maxsock = new_fd;  
  143.                         }//if  
  144.                         else   
  145.                         {  
  146.                                 printf("max connections arrive, exit\n");  
  147.                                 send(new_fd, "bye", 4, 0);  
  148.                                 continue;  
  149.                         }  
  150.                 }//if (FD_ISSET(sock_fd, &fdsr))  
  151.                 showclient();  
  152.         }//while  
  153.         // close other connections  
  154.         for (i = 0; i < BACKLOG; i++)   
  155.         {  
  156.                 if (fd_access[i] != 0)   
  157.                 {  
  158.                         close(fd_access[i]);  
  159.                 }  
  160.         }  
  161.         exit(0);  
  162. }  
  163. (END)   

代码借鉴了很多牛人的博客,最后形成了这个服务器的代码,衷心的感谢各位技术牛人无私的奉献,谢谢~~·


FROM: http://blog.csdn.net/xluren/article/details/8045230

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值