稍加改进的多路复用--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 */
};
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淘汰掉了
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。