http://blog.csdn.net/xluren/article/details/8206371
結構體pollfd
struct pollfd
{
int fd; ? ? ? ? ? ? ? //file descriptor
short event; ? //event of interest on fd
short reven; ?//event that occurred on fd
}
每一個pollfd結構體指定了一個被監視的文件描述符,可以傳遞多個結構體,指示poll()監視多個文件描述符。每個結構體的events域是監視該文件描述符的事件掩碼,由用戶來設置這個域。revents域是文件描述符的操作結果事件掩碼。內核在調用返回時設置這個域。events域中請求的任何事件都可能在revents域中返回。
pollfd結構體合法的事件
POLLIN
有數據可讀。
POLLRDNORM
有普通數據可讀。
POLLRDBAND
有優先數據可讀。
POLLPRI
有緊迫數據可讀。
POLLOUT
寫數據不會導致阻塞。
POLLWRNORM
寫普通數據不會導致阻塞。
POLLWRBAND
寫優先數據不會導致阻塞。
POLLMSG
SIGPOLL 消息可用。
此外,revents域中還可能返回下列事件:
POLLER
指定的文件描述符發生錯誤。
POLLHUP
指定的文件描述符掛起事件。
POLLNVAL
指定的文件描述符非法。
這些事件在events域中無意義,因為它們在合適的時候總是會從revents中返回。使用poll()和select()不一樣,你不需要顯式地請求異常情況報告。
POLLIN | POLLPRI等價于select()的讀事件,POLLOUT |POLLWRBAND等價于select()的寫事件。POLLIN等價于POLLRDNORM |POLLRDBAND,而POLLOUT則等價于POLLWRNORM。
例如,要同時監視一個文件描述符是否可讀和可寫,我們可以設置 events為POLLIN |POLLOUT。在poll返回時,我們可以檢查revents中的標志,對應于文件描述符請求的events結構體。如果POLLIN事件被設置,則文件描述符可以被讀取而不阻塞。如果POLLOUT被設置,則文件描述符可以寫入而不導致阻塞。這些標志并不是互斥的:它們可能被同時設置,表示這個文件描述符的讀取和寫入操作都會正常返回而不阻塞。
timeout參數指定等待的毫秒數,無論I/O是否準備好,poll都會返回。timeout指定為負數值表示無限超時;timeout為0指示poll調用立即返回并列出準備好I/O的文件描述符,但并不等待其它的事件。這種情況下,poll()就像它的名字那樣,一旦選舉出來,立即返回。
函數原型
int poll(struct pollfd fdarray[], nfds_t nfds, int timeout);
poll返回值和錯誤代碼
成功時,poll()返回結構體中revents域不為0的文件描述符個數;如果在超時前沒有任何事件發生,poll()返回0;失敗時,poll()返回-1,并設置errno為下列值之一:
EBADF
一個或多個結構體中指定的文件描述符無效。
EFAULT
fds指針指向的地址超出進程的地址空間。
EINTR
請求的事件之前產生一個信號,調用可以重新發起。
EINVAL
nfds參數超出PLIMIT_NOFILE值。
ENOMEM
可用內存不足,無法完成請求。
以上理論摘自http://www.cnblogs.com/nathan-1988/archive/2012/07/01/2571786.html?謝謝~~~
代碼如下所示:
- #include?<stdio.h>??
- #include?<stdlib.h>??
- #include?<unistd.h>??
- #include?<errno.h>??
- #include?<string.h>??
- #include?<sys/types.h>??
- #include?<sys/socket.h>??
- #include?<netinet/in.h>??
- #include?<arpa/inet.h>??
- #include?<poll.h>??
- #define?MYPORT?6666????//?the?port?users?will?be?connecting?to??
- ??
- #define?BACKLOG?5?????//?how?many?pending?connections?queue?will?hold??
- #ifndef?INFTIM??
- #define?INFTIM?-1??
- #endif??
- #define?BUF_SIZE?1024??
- #define?MAXLINE?100??
- #define?MAXCLIENT?5??
- int?fd_access[BACKLOG];??????
- int?conn_amount;??????
- ??
- int?main(void)??
- {??
- ????????int?sock_fd,?new_fd,len,conn_no;????
- ????????struct?sockaddr_in?server_addr;??????
- ????????struct?sockaddr_in?client_addr;???
- ????????socklen_t?sin_size;??
- ????????char?buf[BUF_SIZE];??
- ????????int?result;??
- ????????int?i;??
- ????????int?maxsock=0;??
- ????????int?conn_fd;??
- ????????struct?pollfd?client[MAXCLIENT];??
- ????????if?((sock_fd?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1)???
- ????????{??
- ????????????????perror("socket");??
- ????????????????exit(1);??
- ????????}???
- ????????server_addr.sin_family?=?AF_INET;???????????
- ????????server_addr.sin_port?=?htons(MYPORT);???????
- ????????server_addr.sin_addr.s_addr?=?INADDR_ANY;???
- ????????memset(server_addr.sin_zero,?'\0',?sizeof(server_addr.sin_zero));??
- ????????if?(bind(sock_fd,?(struct?sockaddr?*)&server_addr,?sizeof(server_addr))?==?-1)???
- ????????{??
- ????????????????perror("bind");??
- ????????????????exit(1);??
- ????????}??
- ????????if?(listen(sock_fd,?BACKLOG)?==?-1)???
- ????????{??
- ????????????????perror("listen");??
- ????????????????exit(1);??
- ????????}??
- ????????printf("listen?port?%d\n",?MYPORT);??
- ??
- ????????sin_size?=?sizeof(client_addr);??
- ????????client[0].fd=sock_fd;??
- ????????client[0].events=POLLIN;??
- ????????for(i=1;i<MAXCLIENT;i++)??
- ????????????????client[i].fd=-1;??
- ????????while?(1)???
- ????????{??
- ????????????????printf("helo\n");??
- ????????????????result=poll(client,maxsock+1,INFTIM);??
- ????????????????if(client[0].revents&POLLIN)??
- ????????????????{??
- ????????????????????????new_fd=accept(sock_fd,(struct?sockaddr*)&client_addr,&sin_size);??
- ????????????????????????for(i?=?1;?i?<?MAXCLIENT;++i)??
- ????????????????????????{??
- ????????????????????????????????if(?client[i].fd?<?0?)??
- ????????????????????????????????{?????????
- ????????????????????????????????????????client[i].fd?=?new_fd;??
- ????????????????????????????????????????client[i].events?=?POLLIN;??
- ????????????????????????????????????????break;??
- ????????????????????????????????}??
- ????????????????????????}??
- ????????????????????????if(?i?==?MAXCLIENT)??
- ????????????????????????{??
- ????????????????????????????????printf("too?many?clients");???
- ????????????????????????????????exit(1);??
- ????????????????????????}??
- ????????????????????????if(?i?>?maxsock?)??
- ????????????????????????????????maxsock?=?i;??
- ????????????????????????if(?--result<=?0?)??
- ????????????????????????????????continue;??
- ????????????????}??
- ????????????????for(i?=?1;?i?<=?maxsock;?i++)??
- ????????????????{??
- ????????????????????????if(?(conn_fd?=?client[i].fd)?<?0)??
- ????????????????????????????????continue;??
- ????????????????????????if(client[i].revents?&?(POLLIN?|?POLLERR))??
- ????????????????????????{??
- ????????????????????????????????if(?(len?=?read(conn_fd,?buf,?MAXLINE))?<?0)???
- ????????????????????????????????{??
- ????????????????????????????????????????if(?errno?==?ECONNRESET)??
- ????????????????????????????????????????{??
- ????????????????????????????????????????????????close(conn_fd);??
- ????????????????????????????????????????????????client[i].fd?=?-1;??
- ????????????????????????????????????????}??
- ????????????????????????????????????????else??
- ????????????????????????????????????????????????perror("read?error");??
- ????????????????????????????????}??
- ????????????????????????????????else?if(len?==?0)??
- ????????????????????????????????{??
- ????????????????????????????????????????close(conn_fd);??
- ????????????????????????????????????????client[i].fd?=?-1;??
- ????????????????????????????????}??
- ????????????????????????????????else??
- ????????????????????????????????????????printf("%s\n",buf);??
- ????????????????????????????????if(--conn_no?<=?0)??
- ????????????????????????????????????????break;??
- ??
- ????????????????????????}??
- ????????????????}??
- ????????}??
- ????????exit(0);??
- }??
- ??
- (END)???
以上是服務器端
客戶端代碼見http://blog.csdn.net/xluren/article/details/8043484#t15