I/O多路复用之poll
来源:互联网 发布:老外中国快递知乎 编辑:程序博客网 时间:2024/05/22 04:48
I/O多路复用之poll
在select()函数中,对象集合不允许为非法值,而poll()函数对于对象的集合没有限制,其操作与select略有不同。
A、管理对象及事件
structpollfd {
int fd; /* 等待的对象file descriptor */
short events; /* 等待的事件requested events*/
short revents; /* 返回事件结果returned events*/
};
读事件:POLLIN
写事件:POLLOUT
B、通知内核要等谁等什么事件,并等,直到事件发生返回结果
功能:通知内核并等待事件的发生
参数:
struct pollfd *fds - 指向管理结构体的首地址
nfds_t nfds - 成员数量(监测对象数量)
int timeout - 超时时间(单位:毫秒)
0:非阻塞
合理一个值:时间到即超时
-1:阻塞(-1的补码即是最大的整数,等待时间最长即为阻塞)
返回值:
-1 :失败
0 :超时
>0: 有事件发生
intpoll(struct pollfd *fds, nfds_t nfds, int timeout);
C、轮询(是谁是什么事情)
for(inti = 0; i < nfds; i++){
D、测试是谁是什么事情
if(POLLIN & fds[i].revents){
E、完成读
read(fds[i].fd,...);
}
if(POLLOUT & fds[i].revents){
E、完成写
write(fds[i].fd,...);
}
}
利用poll()构建一个模拟并发服务器(实现多连接):
#include <stdio.h>#include <string.h>#include <sys/types.h> #include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <poll.h>#define MAX 1024#define FDMAX 1024int init_server(const char *ipstr, unsigned short port, int backlog){int s = socket(AF_INET, SOCK_STREAM, 0);if(0 > s){perror("socket");return -1;}struct sockaddr_in addr = {.sin_family = AF_INET,.sin_port = htons(port),.sin_addr = {.s_addr = (NULL == ipstr ? INADDR_ANY : inet_addr(ipstr)),},};memset(addr.sin_zero, 0, sizeof(addr.sin_zero));socklen_t len = sizeof(addr);if(0 > bind(s, (struct sockaddr *)&addr, len)){perror("bind");return -1;}if(0 > listen(s, backlog)){perror("listen");return -1;}return s;}int main(){int s = init_server(NULL, 8888, 1);if(0 > s){return -1;}int i;/*pfd[0]用于监听网络连接,其余用于等待事件的发生。*/struct pollfd pfd[FDMAX]; for(i = 1; i < FDMAX; i++){pfd[i].fd = -1;pfd[i].events = POLLIN;pfd[i].revents= 0;}pfd[0].fd = s;pfd[0].events = POLLIN;pfd[0].revents= 0;while(1){int ret = poll(pfd, FDMAX, -1);if(0 > ret){ //失败perror("select");break;}else if(0 == ret){ //超时printf("Timeout\n");continue;}if(POLLIN & pfd[0].revents){ //监听网络连接请求struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));socklen_t len = sizeof(addr);int rws = accept(s, (struct sockaddr*)&addr, &len);if(0 > rws){perror("accept");return -1;}printf("a nen comming [%s:%u] \n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));/*文件描述符是依次递增的,每个进程运行时系统会为进程打开stdin(0)、stdout(1)、stderr(2)3个文件描述符,之后为socket创建一个文件描述符(3),pfd[0]存储socket创建的描述符,所以请求连接的文件描述符应从pfd[1]开始,请求连接的文件描述符 - socket文件描述符即为请求连接的文件描述符的位置*/int id = rws - s; if(id == FDMAX){close(rws);printf("No more space.\n");}else{pfd[id].fd = rws;}}for(i = 1; i < FDMAX; i++){ //轮询if(POLLIN & pfd[i].revents){ //是否有事件发生char buf[MAX];memset(buf, 0, MAX);int len = read(pfd[i].fd, buf, MAX-1);if(0 >= len){printf("read [%d] fail .\n", pfd[i].fd);close(pfd[i].fd);pfd[i].fd = -1;}else{printf("sock[%d], RECV[%dbytes]:%s\n", pfd[i].fd, len, buf);}}}}close(s);}
- I/O多路复用之poll
- I/O 多路复用之poll
- I/O多路复用之poll
- I/O多路复用之poll
- I/O多路复用之poll
- I/O多路复用之poll
- I/O多路复用之poll
- poll() | 多路复用 I/O
- poll() | 多路复用 I/O
- I/O多路复用poll
- I/O多路复用技术之 - poll
- I/O 多路复用之 Event Poll
- I/O多路复用之select/poll/epoll
- I/O多路复用之poll模型
- I/O多路复用之POLL系统调用
- I/O多路复用之poll函数分析
- Linux--高级I/O多路复用之Poll
- I/O多路复用之poll服务器
- 杭州电子科技大学acm-2001
- poj(2528)——Mayor's posters(线段树+离散化)
- hdu 1233 还是畅通工程 (克鲁斯卡尔裸题)
- 线性表顺序存储结构
- 九度 Online Judge 算法 刷题 题目1089:数字反转
- I/O多路复用之poll
- Eclipse插件安装
- Lua学习笔记--环境配置&Hello World
- 贪心算法New Year BonusGrant
- 供应商信息一览
- Tomcat Web
- I/O多路复用之-epoll
- [leetcode-138]Copy List with Random Pointer(java)
- 常用的Javascript设计模式