用poll 实现并发服务器

来源:互联网 发布:djvu阅读器 知乎 编辑:程序博客网 时间:2024/04/28 04:23

poll函数类似于select函数,但是它的程序员接口不同,尽管它也可用于任何类型 文件描述符。与select不同,poll不为每个状态(可读,可写,异常状态)构造一个描述符集,而是构造一个pollfd结构数组,每个数组元素指定一个描述符编号以及对其所关心的状态

[cpp] view plaincopyprint?
  1. struct pollfd {  
  2.     int fd;             //file descriptor to check  
  3.     short events;       //events of interest on fd  
  4.     short revents;      //events that occured on fd  
  5. };  
struct pollfd {int fd;//file descriptor to checkshort events;//events of interest on fdshort revents;//events that occured on fd};
同样实现一个TCP服务器看看。

[cpp] view plaincopyprint?
  1. #include<stdio.h>   
  2. #include<stdlib.h>   
  3. #include<string.h>   
  4. #include<sys/types.h>   
  5. #include<sys/socket.h>   
  6. #include<netinet/in.h>   
  7. #include<arpa/inet.h>   
  8. #include<sys/poll.h>   
  9. #include<limits.h>   
  10.   
  11. #define MAX_LISTEN 5   
  12. #define PORT 1987   
  13. #define IP "127.0.0.1"   
  14.   
  15. #define MAX_POLL 100   
  16.   
  17. //#define POLLRDNORM 0x0040   
  18.   
  19. int main()  
  20. {  
  21.     int conn_fd;  
  22.     int sock_fd = socket(AF_INET,SOCK_STREAM,0);  
  23.     if (sock_fd < 0) {  
  24.         perror("create socket failed");  
  25.         exit(1);  
  26.     }  
  27.   
  28.     struct sockaddr_in addr_client;  
  29.     int client_size = sizeof(struct sockaddr_in);  
  30.   
  31.     struct sockaddr_in addr_serv;  
  32.     memset(&addr_serv, 0, sizeof(addr_serv));  
  33.     addr_serv.sin_family = AF_INET;  
  34.     addr_serv.sin_port = htons(PORT);  
  35.     addr_serv.sin_addr.s_addr = inet_addr(IP);  
  36.   
  37.     if (bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in)) < 0) {  
  38.         perror("bind error");  
  39.         exit(1);  
  40.     }  
  41.   
  42.     if (listen(sock_fd,MAX_LISTEN) < 0) {  
  43.         perror("listen failed");  
  44.         exit(1);  
  45.     }  
  46.   
  47.     //   
  48.     int recv_num;  
  49.     int send_num;  
  50.     char recv_buf[100];  
  51.     char send_buf[100];   
  52.   
  53.     //initial "poll" elements   
  54.     int i, ready;  
  55.     struct pollfd client[MAX_POLL];  
  56.   
  57.     client[0].fd = sock_fd;  
  58.     client[0].events = POLLRDNORM;  
  59.     for (i = 1;i < MAX_POLL; i ++) {  
  60.         client[i].fd = -1;  
  61.     }  
  62.     int maxi = 0;  
  63.   
  64.   
  65.     while (1) {  
  66.   
  67.         ready = poll(client, maxi + 1, 0);  
  68.           
  69.         //create new connection  
  70.         if (client[0].revents & POLLRDNORM) {  
  71.             conn_fd = accept(sock_fd, (struct sockaddr *)&addr_client, &client_size);  
  72.             if (conn_fd < 0) {  
  73.                 perror("accept failed");  
  74.                 exit(1);  
  75.             }  
  76.   
  77.             for (i = 1;i < MAX_POLL;i ++) {  
  78.                 if (client[i].fd < 0) {  
  79.                     client[i].fd = conn_fd;  
  80.                     break;  
  81.                 }  
  82.             }  
  83.             if (i == MAX_POLL) {  
  84.                 perror("too many clients");  
  85.                 exit(1);  
  86.             }  
  87.   
  88.             if (i > maxi)  
  89.                 maxi = i;  
  90.         }  
  91.           
  92.         //send and receive   
  93.         for (i = 1; i <= maxi; i ++) {  
  94.             if (client[i].fd >= 0 && (client[i].revents & (POLLRDNORM | POLLERR))) {  
  95.   
  96.                 recv_num = recv(client[i].fd, recv_buf, sizeof(recv_buf), 0);  
  97.                 if (recv_num <= 0) {  
  98.                     close(client[i].fd);  
  99.                     client[i].fd = -1;  
  100.                 } else {  
  101.                     recv_buf[recv_num] = '\0';  
  102.                     memset(send_buf,0,sizeof(send_buf));  
  103.                     sprintf(send_buf, "server proc got %d bytes\n", recv_num);  
  104.                     send_num = send(client[i].fd, send_buf, strlen(send_buf), 0);  
  105.                     if (send_num <= 0) {  
  106.                         close(client[i].fd);  
  107.                         client[i].fd = -1;  
  108.                     }  
  109.                 }  
  110.             }  
  111.         }  
  112.     }  
  113.           
  114.     close(sock_fd);  
  115.     return 0;  
  116. }  
原创粉丝点击