1.poll 的接口介绍

poll 系统调用和 select 类似,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者。poll 的原型如下:

#include <poll.h>int poll( struct pollfd *fds, nfds_t nfds, int timeout);
/*
poll 系统调用成功返回就绪文件描述符的总数,超时返回 0,失败返回-1
nfds 参数指定被监听事件集合 fds 的大小。
timeout 参数指定 poll 的超时值,单位是毫秒,timeout 为-1 时,poll 调用将永久阻塞,直到某个事件发生,timeout 为 0 时,poll 调用将立即返回。
*//*
fds 参数是一个 struct pollfd 结构类型的数组,它指定所有用户感兴趣的文件描述符上发生的可读、可写和异常等事件。pollfd 结构体定义如下:
*/
12. struct pollfd
13. {14. int fd; // 文件描述符
15. short events; // 注册的关注事件类型
16. short revents; // 实际发生的事件类型,由内核填充
17. };
//其中,fd 成员指定文件描述符,events 成员告诉 poll 监听 fd 上的哪些事件类型。它是一系列事件的按位或,revents 成员则有内核修改,通知应用程序 fd 上实际发生了哪些事件。poll 支持的事件类型如下

2.示例代码

服务端示例代码

#define _GNU_SOURCE#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/poll.h>#define MAX_FD 1024
#define DATALEN 128//初始化服务器的socket套接字
int InitSocket()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);assert(sockfd != -1);struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("127.0.0.1");int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));assert(res != -1);res = listen(sockfd,5);assert(res != -1);return sockfd;
}//初始化记录服务器套接字的数组
void InitPollFds(struct pollfd fds[],int n)
{for(int i = 0; i < n; i++){fds[i].fd = -1;}
}//将套接字描述符添加到数组中
void AddFdToPollFds(struct pollfd fds[],int n, int fd, short events)
{for(int i = 0; i < n; i++){if(fds[i].fd == -1){fds[i].fd = fd;fds[i].events = events;break;}}
}//接收客户端连接
void GetClientLink(struct pollfd fds[],int n, int sockfd)
{struct sockaddr_in caddr;memset(&caddr,0,sizeof(caddr));int len = sizeof(caddr);int c = accept(sockfd,(struct sockaddr*)&caddr,&len);if(c < 0){return;}else//接收连接成功,将客户端套接字描述符和我们关心的事件类型添加到fds中{printf("cilent %d  link sucess\n",c);AddFdToPollFds(fds,n,c,POLLIN | POLLRDHUP);//关心事件类型为可读数据和客户端关闭}
}//处理客户端数据 
int DealClientData(int clifd)
{char data[DATALEN] = {0};int num = recv(clifd,data,DATALEN-1,0);if(num <= 0)//读取失败,返回{return -1;}else{printf("%d:%s\n",clifd,data);send(clifd,"OK",2,0);}return 0;
}//处理poll返回的就绪事件
void DealReadyEvent(struct pollfd fds[],int n,int sockfd)
{for(int i = 0; i < n; i++){if(fds[i].fd != -1){if(fds[i].revents & POLLRDHUP)//判断客户端是否关闭,客户端关闭,这里也要关闭客户端描述符{printf("client %d over\n",fds[i].fd);close(fds[i].fd);fds[i].fd = -1;continue;}else if(fds[i].revents & POLLIN)//客户端有可读事件处理{if(fds[i].fd == sockfd)//如果是服务器套接字描述符有可读事件处理,就是有客户端连接{GetClientLink(fds,n,fds[i].fd);}else//客户端套接字描述符有可读事件处理,去读取数据{DealClientData(fds[i].fd);}}}}
}int main()
{int sockfd = InitSocket();assert(sockfd != -1);struct pollfd fds[MAX_FD];InitPollFds(fds,MAX_FD);AddFdToPollFds(fds,MAX_FD,sockfd,POLLIN);while(1){int n = poll(fds,MAX_FD,5000);//5秒时间if(n < 0)//poll失败,服务器退出{printf("poll error\n");break;}else if(n == 0)//规定时间内没有就绪事件产生{printf("time out\n");continue;}else//有就绪事件产生{DealReadyEvent(fds,MAX_FD,sockfd);}}exit(0);
}

客户端示例代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<sys/socket.h>
#include<arpa/inet.h>int InitSocket()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);assert(sockfd != -1);struct sockaddr_in saddr;saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("127.0.0.1");int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));assert(res != -1);return sockfd;
}int main()
{int sockfd = InitSocket();assert(sockfd != -1);while(1){printf("please input:\n");char buff[128] = {0};fgets(buff,127,stdin);if(strncmp(buff,"end",3) == 0){break;}int n = send(sockfd,buff,strlen(buff)-1,0);if(n < 0){printf("send error\n");break;}memset(buff,0,128);n = recv(sockfd,buff,127,0);if(n < 0){printf("recv error\n");break;}printf("%s\n");}close(sockfd);exit(0);}

运行结果
服务端:

客户端1和客户端2:

I/O复用函数的使用——poll相关推荐

  1. I/O复用函数的使用——epoll

    1.epoll的接口介绍 epoll 是 Linux 特有的 I/O 复用函数.它在实现和使用上与 select.poll 有很大差异.首先,epoll 使用一组函数来完成任务,而不是单个函数.其次, ...

  2. I/O复用:select、poll和epoll函数

    I/O复用场景: 当客户处理多个描述符(通常是交互式输入和网络套接字)时,必须使用I/O复用. 一个客户同时处理多个套接字. 一个TCP服务器既要处理监听套接字,又要处理已连接套接字. 一个服务器既要 ...

  3. UNIX网络编程:I/O复用技术(select、poll、epoll)

    http://blog.csdn.net/dandelion_gong/article/details/51673085 Unix下可用的I/O模型一共有五种:阻塞I/O .非阻塞I/O .I/O复用 ...

  4. scala tail recursive优化,复用函数栈

    在scala中如果一个函数在最后一步调用自己(必须完全调用自己,不能加其他额外运算子),那么在scala中会复用函数栈,这样递归调用就转化成了线性的调用,效率大大的提高.If a function c ...

  5. linux的poll_wait函数,select() 与 poll()两个函数接口的作用

    select()函数的作用 系统调用select和poll的后端实现,用这两个系统调用来查询设备是否可读写,或是否处于某种状态.如果poll为空,则驱动设备会被认为即可读又可写,返回值是一个状态掩码 ...

  6. poll函数_I/O复用 - 三组I/O复用函数的比较

    在之前的文章中 I/O复用 - epoll 和 I/O复用 - select&poll 中我们讨论了三组I/O复用的系统调用,这3组系统调用都能同时监听多个文件描述符.它们将等待由timeou ...

  7. 多路I/O复用的三个函数select、poll、epoll

    多路I/O复用 一.select 1.函数原型 2. 使用步骤 二.poll 1. 函数原型 三.epoll 1. 函数原型 2. 详解 一.select 1.函数原型 函数原型 #include&l ...

  8. linux io端口复用,Linux系统IO复用接口(select、poll、epoll)

    epoll仅仅是一个异步事件的通知机制,其本身并不作任何的IO读写操作,它只负责告诉你是不是可以读或可以写了,而具体的读写操作,还要应用程序自己来完成.epoll仅提供这种机制是非常好的,它保持了事件 ...

  9. I/O复用函数的比较

    select poll 和 epoll 三组I/O复用系统调用都能够同时监听多个文件描述符.它们将等到由timeout参数指定的超时时间,直到一个或者多个文件描述符上有时间发生时返回,返回值就是就绪的 ...

最新文章

  1. 【学习笔记】CO内部订单
  2. AC日记——最大子段和 洛谷 P1115
  3. 算法设计与分析——动态规划——最大字段和问题
  4. C++异常之异常说明
  5. boot spring 没有父子容器_理解 MyBatis 是如何在 Spring 容器中初始化的
  6. MySQL优化常见Extra分析——慢查询优化
  7. android实现字体滚动,Android实现字幕滚动的方法
  8. 基于CSS class的事件监听管理机制 (转)
  9. google 搜索关键字技巧 google darking
  10. RuntimeError: Exporting the operator var to ONNX opset version 11 is not supported. Please open a bu
  11. 中国邮政国际挂号信网上查询
  12. 使用Consol线连接路由器
  13. 企业邮箱登录入口,邮箱登陆登录入口有哪些?
  14. [emWin]利用内存设备加速GIF图片显示——2021.03
  15. VMware 安装 CentOS 8.0
  16. Unity 制作font字体
  17. 【pandas】将单元格中的多个数据拆分为多行数据(explode),以csv文件为源文件进行处理
  18. Redis核心数据结构ZSET、GeoHash 、 Stream--排行榜、消息Pull推送、附近搜索、布隆过滤器 、IM聊天室
  19. java 验证码_java实现简单的验证码功能
  20. Excel批量自动处理工具(写公式、查找提取、替换、批量清除、合并、表格式转换....)

热门文章

  1. 究竟什么能使得生活变得圆满?
  2. [网络安全自学篇] 四十二.DNS欺骗和钓鱼网站原理详解及防御机理
  3. 2020年第十一届蓝桥杯 - 省赛 - Python大学组 - G. 单词分析
  4. G6 图可视化引擎——入门教程——插件与工具
  5. 征战蓝桥 —— 2013年第四届 —— C/C++A组第4题——颠倒的价牌
  6. 大数据互联网架构阶段 Spring框架导致的406错误
  7. ROS-Kinetic 中使用XSENS MTI 1 姿态传感器
  8. 【Linux系统编程】Linux文件操作
  9. 小程序服务器七牛云,基于七牛云 API 开发的微信小程序 SDK
  10. seer文献_文献解读 | 师兄带你读一篇免疫浸润3分文章!