一、poll
創(chuàng)新互聯(lián)建站專注于網(wǎng)站建設(shè)|成都網(wǎng)站改版|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計與制作經(jīng)驗,為許多企業(yè)提供了網(wǎng)站定制設(shè)計服務(wù),案例作品覆蓋濕噴機等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身設(shè)計品質(zhì)網(wǎng)站。
poll的實現(xiàn)和select非常相似,只是描述fd集合的方式不同,poll使用pollfd結(jié)構(gòu)而不是select的fd_set結(jié)構(gòu),其他的都差不多。
二、poll相關(guān)函數(shù)
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
//fds: pollfd結(jié)構(gòu)體
events: 要監(jiān)視的事件
revents: 已經(jīng)發(fā)生的事件, 設(shè)置標(biāo)志 來反映相關(guān)條件的存在
常量 說明
POLLIN 普通或優(yōu)先級帶數(shù)據(jù)可讀
POLLRDNORM 普通數(shù)據(jù)可讀
POLLRDBAND 優(yōu)先級帶數(shù)據(jù)可讀
POLLPRI 高優(yōu)先級數(shù)據(jù)可讀
POLLOUT 普通數(shù)據(jù)可寫
POLLWRNORM 普通數(shù)據(jù)可寫
POLLWRBAND 優(yōu)先級帶數(shù)據(jù)可寫
// 只能作為描述字的返回結(jié)果存儲在revents中
POLLERR 發(fā)生錯誤
POLLHUP 發(fā)生掛起
POLLNVAL 描述字不是一個打開的文件
struct pollfd { int fd; /* 文件描述符 */ short events; /* 請求的事件 */ short revents; /* 返回的事件 */ };
//nfds: 要監(jiān)視的描述符的數(shù)目
//timeout:指定poll在返回前沒有接收事件時應(yīng)該等待的時間【單位:ms】。
INFTIM: 永不超時
0 :立即返回
>0: 等待指定的時間
2、特點:
pollfd并沒有最大數(shù)量限制(但是數(shù)量過大后性能也是會下降)。
和select函數(shù)一樣,poll返回后,需要輪詢pollfd來獲取就緒的描述符。
select和poll都需要在返回后,通過遍歷文件描述符來獲取已經(jīng)就緒的socket。事實上,同時連接的大量客戶端在一時刻可能只有很少的處于就緒狀態(tài),因此隨著監(jiān)視的描述符數(shù)量的增長,其效率也會線性下降。
三、poll 服務(wù)器
#include <stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netinet/in.h> #include<unistd.h> #include<string.h> #include<errno.h> #include<sys/select.h> #include<sys/poll.h> #define _BACKLOG_ 5 #define _MAX_NUM_ 64 void usage(const char *proc) { printf("Usage: %s [ip][port]\n",proc); } static int startup(const char *ip,const 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_port=htons(port); local.sin_addr.s_addr=inet_addr(ip); if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0) { perror("bind"); exit(2); } if(listen(sock,_BACKLOG_) < 0) { perror("listen"); exit(3); } return sock; } static int poll_server(int listen_sock) { struct sockaddr_in client; socklen_t len=sizeof(client); struct pollfd fds[_MAX_NUM_]; fds[0].fd=listen_sock; fds[0].events=POLLIN; fds[0].revents=0; size_t i=0; for(;i<_MAX_NUM_;++i) { fds[i].fd=-1; fds[i].events=0; fds[i].revents=0; } int max_fd=1; int timeout=5000; while(1) { switch(poll(fds,max_fd,timeout)) { case -1://error perror("poll"); break; case 0://timeout printf("poll timeout"); break; default://normal { for(i=0;i<_MAX_NUM_;++i) { //is listen events ready? if(fds[i].fd == listen_sock && fds[i].revents == POLLIN) { int accept_sock=accept(listen_sock,(struct sockaddr*)&client,&len); if(accept_sock < 0) { perror("accept"); continue; } printf("get a client...[ip: %s][port: %d]\n",\ inet_ntoa(client.sin_addr),ntohs(client.sin_port)); for(i=0;i<_MAX_NUM_;++i) { if(fds[i].fd == -1) { fds[i].fd=accept_sock; fds[i].events=POLLIN; max_fd++; break; } } if(i == _MAX_NUM_) { close(accept_sock); } } else if(fds[i].fd > 0 && fds[i].revents == POLLIN) { char buf[1024]; ssize_t _size=read(fds[i].fd,buf,sizeof(buf)-1); if(_size > 0)//read success { buf[_size]='\0'; printf("Client # %s",buf); } else if(_size == 0)//client close { printf("clint close...\n"); struct pollfd tmp=fds[i]; fds[i]=fds[max_fd-1]; close(fds[max_fd-1].fd); fds[max_fd-1].fd=-1; fds[max_fd-1].events=0; fds[max_fd-1].revents=0; --max_fd; } } else {} } } break; } } return 0; } int main(int argc,char *argv[]) { if(argc != 3) { usage(argv[0]); return 1; } char *ip=argv[1]; int port=atoi(argv[2]); int listen_sock=startup(ip,port); poll_server(listen_sock); close(listen_sock); return 0; }
總結(jié):
poll在返回后,需要通過遍歷文件描述符來獲取已經(jīng)就緒的socket從而進行下一步操作;而且使用完監(jiān)聽套接字后,都需要進行關(guān)閉。
標(biāo)題名稱:I/O多路轉(zhuǎn)接 ---- poll
網(wǎng)站地址:http://jinyejixie.com/article20/jopdco.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、企業(yè)建站、域名注冊、網(wǎng)站營銷、ChatGPT、虛擬主機
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)