稍加改进的多路复用--poll
poll是一个在select上稍加改进的多路复用版本,不久后就被功能完善的epoll所取代,它与select的区别在于select的返回通过输入参数来返回,这样每次都要添加要关心的文件描述符到其文件描述符集中,而poll设置了一个结构体指针参数,通过他就可以知道状态变化,但免不了的是依旧需要遍历整个buf,它的大小可以由用户自定义,但是过于大的集合会使得服务器负担大大加重,而太小的集合又因为大多的socket都在等待数据到来,效率上又会下滑很多,所以poll很尴尬。
poll的函数
#include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout); struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ };
poll的函数与select不一样的地方就是它的fds参数,他是一个结构体指针,结构体的定义就是下面那个
struct pollfd,其中的events是设置的时候所要关心的时间,revents是输出当大于零的时候便说明发生了event所设置的情况,revents不用手动清空,他会自动清空。
因为和select差不多,就直接看代码吧
下面是实现的一个简单的poll版本的tcp服务器
因为前面的设置监听套接字和之前的都一样就忽略了
43 void PollServer(int sock) 44 { 45 int i=0; 46 int max_fd=-1; 47 struct pollfd fds[_MAX_FDS_]; 48 for(;i<_MAX_FDS_;i++) 49 { 50 fds[i].fd=-1; 51 } 52 fds[0].fd=sock; 53 max_fd=sock; 54 fds[0].events=POLLIN; //设置为所关心的事件 55 int timeout; 56 while(1) 57 { 58 int new_sock=-1; 59 60 struct sockaddr_in client; 61 socklen_t client_len=sizeof(client); 62 63 fds[0].fd=sock; 64 fds[0].events=POLLIN; 65 timeout=5000; 66 switch(poll(fds,max_fd+1,timeout))//依然需要循环 67 { 68 case -1: 69 perror("poll"); 70 continue; 71 case 0: 72 printf("timeout\n"); 73 continue; 74 default: 75 { 76 for(i=0;i<_MAX_FDS_;i++) 77 { 78 int fd=fds[i].fd; 79 if(fd==sock&&fds[i].revents>0) //当有新的连接时 80 { 81 new_sock=accept(sock,(struct sockaddr*)\ 82 &client,&client_len); 83 printf("%d\n",new_sock); 84 for(i=0;i<_MAX_FDS_;i++) 85 { 86 if(fds[i].fd<0) 87 { 88 fds[i].fd=new_sock; 89 fds[i].events=POLLIN; 90 break; 91 } 92 } 93 if(i==_MAX_FDS_) 94 { 95 close(new_sock); 96 } 97 } 98 else if(fd>0&&fds[i].revents>0) //当有需要读的数据时 99 { 100 char buf[1024]; 101 memset(buf,'\0',sizeof(buf)); 102 ssize_t size=read(fd,buf,sizeof(buf)-1); 103 if(size>0) 104 { 105 buf[size]='\0'; 106 printf("client::%s\n",buf); 107 }else if(size==0){ 108 close(fd); 109 fds[i].fd=-1; 110 fds[i].events=-1; 111 }else{ 112 perror("read"); 113 continue; 114 } 115 } 116 } 117 } 118 } 119 } 120 } 121
poll和select的区别并不大,所以很快被epoll淘汰掉了
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。