I/O多路转接之poll
来源:互联网 发布:牙齿矫正知乎 编辑:程序博客网 时间:2024/05/16 13:41
poll采用了一个单独的结构体pollfd数组,由fds指针指向这个组。pollfd结构体定义如下:
struct pollfd {
int fd; //文件描述符
short events; //当下文件描述符关心的事件
short revents; //文件描述符关心的事件就绪
};
每一个pollfd结构体指定了一个被监视的文件描述符,可以传递多个结构体,指示poll()监视多个文件描述符。每个结构体的events域是监视该文件描述符关心的事件,由用户来设置这个域。revents域是文件描述符的关心事件发生了。内核在调用返回时设置这个域。events域中请求的任何事件都可能在revents域中返回。
函数原型:int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
参数依次为: 结构体数组、有效文件描述符个数、超时时间
poll优点
1、poll() 不要求开发者计算最大文件描述符加一的大小。
2、poll() 在应付大数目的文件描述符的时候相比于select速度更快 。
3、它没有最大连接数的限制,原因是它是基于链表来存储的。
poll缺点
1、大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。
2、与select一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
使用poll监控输入输出
#include<stdio.h>#include<poll.h>#include<stdlib.h>#include<string.h>int main(int argc,char *argv[]){ struct pollfd _poll[1]; _poll[0].fd=0; _poll[0].events=POLLIN; _poll[0].revents=0; int timeout=3000; int i=0; char buf[1024];while(1){ switch(poll(_poll,1,timeout)) { case 0: printf("timeout"); break; case -1: printf("poll"); break; default: { for(i=0;i<2;i++) { if((_poll[0].fd==0)&&(_poll[0].revents)&POLLIN) { ssize_t s=read(0,buf,sizeof(buf)-1); if(s>0) { buf[s]=0; if(strncmp(buf,"hello poll",10)==0) { close(_poll[i].fd); return 1; } printf("ecjo:%s\n",buf); } } } } break; }}return 0;}
使用poll实现一个服务器;
#include<stdio.h>#include<stdlib.h>#include<poll.h>#include<unistd.h>#include<sys/types.h>#include<sys/socket.h>#include<arpa/inet.h>#include<netinet/in.h>#include<string.h>static void usage(char *proc){ printf("usage:%s [local_ip] [local_port]\n",proc);}int startup(char* _ip,int _port) { //create socket int sock=socket(AF_INET,SOCK_STREAM,0); if(sock<0) { perror("socket"); return 2; } //port multiplexing int flg=1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&flg,sizeof(flg)); struct sockaddr_in local; local.sin_family=AF_INET; local.sin_addr.s_addr=inet_addr(_ip); local.sin_port=htons(_port); //bind if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) { perror("bind"); return 3; } //listen if(listen(sock,10)<0) { perror("listen"); return 4; } return sock;}int main(int argc,char *argv[]){ if(argc!=3) { usage(argv[0]); return 1; } int listen_sock=startup(argv[1],atoi(argv[2])); struct pollfd fd_set[2]; fd_set[0].fd=listen_sock; fd_set[0].events=POLLIN; fd_set[0].revents=0; int timeout=2000; int n=sizeof(fd_set)/sizeof(fd_set[0]); struct sockaddr_in client; socklen_t len=sizeof(client); int i=1; for(;i<n;i++) { fd_set[i].fd=-1; } int maxfd=0; while(1) { switch(poll(fd_set,maxfd+1,timeout)) { case 0: printf("timeout..\n"); break; case -1: printf("poll"); break; default: { for(i=0;i<n;i++) { if((fd_set[i].fd==listen_sock)&& \ (fd_set[i].revents)&POLLIN) { int new_sock=accept(listen_sock,\ (struct sockaddr*)&client,&len); if(new_sock<0) { perror("accept"); continue; } printf("get a new client\n"); int j=0; for(j=0;j<n;j++) { if(fd_set[j].fd==-1) { fd_set[j].fd=new_sock; fd_set[j].events=POLLIN; fd_set[j].revents=0; break; } } if(j==n) { close(new_sock); } if(j>maxfd) { maxfd=j; } } else if((fd_set[i].fd>0)&& (fd_set[i].revents)&POLLIN) { char buf[1024]; ssize_t s=read(fd_set[i].fd,buf,sizeof(buf)-1); if(s>0) { buf[s]='\0'; printf("client: %s\n",buf); write(fd_set[i].fd,buf,strlen(buf)); } else if(s==0) { close(fd_set[i].fd); int p=1; for(;p<n;i++) { if((fd_set[p].fd!=-1)&&(p!=i)) { int temp=fd_set[i].fd; fd_set[i].fd=fd_set[p].fd; fd_set[p].fd=temp; } } } } } } break; } } return 0;}
阅读全文
0 0
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之poll
- I/O多路转接之select、poll、epoll
- I/O多路转接之poll 函数
- 【计算机网络】I/O多路转接之poll
- I/O多路转接之poll服务器
- Linux—I/O多路转接之poll
- I/O多路转接之poll 函数
- I/O多路转接至poll
- 【Linux】I/O多路转接poll
- I/O多路转接-----poll
- sleep、wait争用锁
- 写在大三末尾:10条不怎么重要的大学建议
- 【Deep Learning学习笔记】Efficient Estimation of Word Representations in Vector Space_google2013 标题:Effic
- SpringBoot简单入门
- 不擅长是因为“方法”不对-读后感
- I/O多路转接之poll
- Arranging Coins
- 从mysql中导出一列数据到txt
- Android launcher -- launcher源码修改 2
- cenos7 的gitlab 搭建和遇到的坑
- Rosalind-计算DNA碱基数
- 【java学习之旅】——Struts2的I18n实现登陆页面中英文切换
- map/set/multi_map/multi_set/unorder_map/unorder_set总结
- 26 register_chrdev函数