poll服务器
来源:互联网 发布:python日常实用小脚本 编辑:程序博客网 时间:2024/06/05 15:47
poll函数:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
- 参数:
- fds:存放需要被检测状态的Socket描述符;与select不同(select函数在调用之后,会清空检测socket描述符的数组),每当调用这个函数之后,系统不会清空这个数组,而是将有状态变化的描述符结构的revents变量状态变化,操作起来比较方便;
- nfds:用于标记数组fds中的struct pollfd结构元素的总数量
- timeout:与select中timeout含义相同,单位是毫秒
- struct polled结构体
struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ };//fd:关心该文件描述符 //events:关心该描述符的事件 //revents:该描述符就绪的事件
- 返回值
- 成功时,poll()返回结构体中revents域不为0的文件描述符个数;如果在超时前没有任何事件发生,poll()返回0;失败时,poll()返回-1
- 事件
- POLLIN 有数据可读。
- POLLRDNORM 有普通数据可读。
- POLLRDBAND 有优先数据可读。
- POLLPRI 有紧迫数据可读。
- POLLOUT 写数据不会导致阻塞。
- POLLWRNORM 写普通数据不会导致阻塞。
- POLLWRBAND 写优先数据不会导致阻塞。
- revents域中还可能返回下列事件
- POLLER 指定的文件描述符发生错误。
- POLLHUP 指定的文件描述符挂起事件。
- POLLNVAL 指定的文件描述符非法。
poll优缺点
- 优点
- poll() 不要求开发者计算最大文件描述符加一的大小
- poll() 在应付大数目的文件描述符的时候相比于select速度更快
- 它没有最大连接数的限制,原因是它是基于链表来存储的
- 缺点
- 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义
- 与select一样,poll返回后,需要轮询pollfd来获取就绪的描述符
//poll服务器代码#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/select.h>#include<arpa/inet.h>#include<netinet/in.h>#include<string.h>#include<poll.h>#include<unistd.h>#define SIZE 1024static void usage(const char* proc){ printf("usage:%s [local_ip] [local_port\n]",proc);}int startup(char* ip,int port){ int sock = socket(AF_INET,SOCK_STREAM,0); if(sock<0){ perror("socket"); exit(2); } struct sockaddr_in client; client.sin_family = AF_INET; client.sin_port = htons(port); client.sin_addr.s_addr = inet_addr(ip); if(bind(sock,(struct sockaddr*)&client,sizeof(client))<0){ perror("bind"); exit(3); } if(listen(sock,10)<0){ perror("bind"); exit(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 pd[SIZE]; int i=0; for(;i<SIZE;++i){ pd[i].fd=-1; } pd[0].fd = listen_sock; pd[0].events = POLLIN; pd[0].revents = 0; int timeout = -1; while(1){ switch(poll(pd,SIZE,timeout)){ case -1: perror("poll"); break; case 0: printf("timeout..\n"); break; default: { i=0; for(;i<SIZE;++i){ if(i==0 && pd[0].revents & POLLIN){ struct sockaddr_in client; socklen_t len = sizeof(client); int new_sock = accept(listen_sock,(struct sockaddr*)&client,&len); if(new_sock<0){ perror("accept"); exit(5); } printf("get a client:[%s:%d]\n",inet_ntoa(client.sin_addr),\ ntohs(client.sin_port)); int j=0; for(j=1;j<SIZE;++j){ if(pd[j].fd<0){ break; } } if(j==SIZE){ printf("pd is full\n"); break; }else{ pd[j].fd = new_sock; pd[j].events = POLLIN; } }else if(i!=0){ if(pd[i].revents & POLLOUT){ char buf[1024]; printf("Please Enter:"); fflush(stdout); read(0,buf,sizeof(buf)-1); write(pd[i].fd,buf,strlen(buf)-1); pd[i].events = POLLIN; }else if(pd[i].revents & POLLIN){ char msg[1024]; ssize_t s = read(pd[i].fd,msg,sizeof(msg)-1); if(s<0){ perror("read"); exit(6); }else if(s==0){ printf("clinet is quit\n"); close(pd[i].fd); pd[i].fd = -1; }else{ msg[s] = 0; printf("client say:%s",msg); pd[i].events = POLLOUT; } }else{ } } } } } } return 0;}
阅读全文
0 1
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll服务器
- poll f服务器
- poll服务器与客户端
- Linux poll服务器
- poll服务器编程综合
- poll->epoll服务器
- 并发服务器poll
- poll服务器---多路连接之 poll
- 用poll 实现并发服务器
- 49-使用 poll 改写服务器
- 安装ElasticSearch过程遇到的坑
- 关于设置背景颜色影响的范围
- 工厂模式
- 基于数组的排序算法
- 问答入门----HTML5 / js多线程
- poll服务器
- mysql 查找具体sql执行性能
- KMP算法的时间复杂度
- TP框架隐藏index.php和Home的访问名
- OpenGL GAO访问冲突(glBindVertexArray)
- Hinton Neural Networks for Machine Learning 第二讲: 感知机-几何描述
- python计算两个地址之间的距离
- [POJ]3164 Command Network 朱刘算法
- 关于多维数组的reshape