I/O多路复用之poll

来源:互联网 发布:js对象数组按属性排序 编辑:程序博客网 时间:2024/05/22 11:41

1、poll的优缺点

poll的优点

1)poll() 不要求开发者计算最大文件描述符加一的大小。 
2)poll() 在应付大数目的文件描述符的时候速度更快,相比于select。 
3)它没有最大连接数的限制,原因是它是基于链表来存储的。

poll的缺点

1)大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。 
2)与select一样,poll返回后,需要轮询pollfd来获取就绪的描述符。


2、poll服务器的简单实现

#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<stdlib.h>#include<unistd.h>#include<arpa/inet.h>#include<poll.h>#include<string.h>#define POLLFD_SIZE 1024struct pollfd array_fd[POLLFD_SIZE];void pd_action(int index){if(array_fd[index].revents & POLLIN){char buf[1024];memset(buf,0,sizeof(buf));ssize_t s = read(array_fd[index].fd,0,sizeof(buf)-1);if(s > 0){buf[s] = 0;printf("client say:%s\n",buf);fflush(stdout);array_fd[index].events = POLLOUT;}else{printf("client quit!\n");fflush(stdout);close(array_fd[index].fd);array_fd[index].fd = -1;//文件描述符初始化为默认值}}else if(array_fd[index].revents & POLLOUT){const char*msg = "HTTP/1.1 200 OK\r\n\r\n<html><br/><h1>hello poll</h1></html>";write(array_fd[index].fd,msg,strlen(msg));array_fd[index].events = POLLIN;}}int startup(const char *_ip,int _port){int sock = socket(AF_INET,SOCK_STREAM,0);if(sock < 0){perror("socket");exit(1);}int opt = 1;setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));struct sockaddr_in local;local.sin_family = AF_INET;local.sin_addr.s_addr = inet_addr(_ip);local.sin_port = htons(_port);if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0){perror("bind");exit(2);}if(listen(sock,10) < 0){perror("listen");exit(3);}return sock;}static void usage(const char *proc){printf("usage:%s[local_ip][local_port]\n",proc);}int main(int argc,char *argv[]){if(argc != 3){usage(argv[0]);return 1;}int listen_sock = startup(argv[1],atoi(argv[2]));array_fd[0].fd = listen_sock;int i = 0;for(;i < POLLFD_SIZE;i++){array_fd[i].fd = -1;}int timeout = -1;while(1){switch(poll(array_fd,POLLFD_SIZE,timeout)){case 0:printf("timeout....\n");break;case -1: perror("poll\n");break;default: { int j = 0;for(;j < POLLFD_SIZE;j++){if(j == 0 && array_fd[j].revents & POLLIN){struct sockaddr_in client;socklen_t len = sizeof(client);int newfd = accept(listen_sock,(struct sockaddr*)&client,&len);if(newfd < 0){ perror("accept\n");continue;}else{printf("get a new client:(%s:%d)\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));int k = 0;for(;k < POLLFD_SIZE;k++){ if(array_fd[k].fd < 0){ array_fd[k].fd = newfd;array_fd[k].events = POLLOUT;break;}}if(k == POLLFD_SIZE){ close(newfd);break;}}}else if(j != 0){pd_action(j);}else{}}}break;}}close(listen_sock);return 0;}




原创粉丝点击