您好,登錄后才能下訂單哦!
稍加改進的多路復用--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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。