IO多路转接之poll

文章目录

  • IO多路转接之poll
    • 一、Poll

一、Poll

  • 1.函数原型:
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
参数 作用
struct pollfd *fds fds是一个poll函数监听的结构列表. 每一个元素中, 包含了三部分内容: 文件描述符, 监听的事件集合, 返回的事件集合
nfds_t nfds nfds表示fds数组的长度
timeout timeout表示poll函数的超时时间, 单位是毫秒(ms)

返回值

  • 返回值小于0, 表示出错;
  • 返回值等于0, 表示poll函数等待超时;
  • 返回值大于0, 表示poll由于监听的文件描述符就绪而返回
  • 2.理解struct pollfd *fds
// pollfd结构
struct pollfd {int fd; /* file descriptor */short events; /* requested events */short revents; /* returned events */
};

其中enent和revent的取值(主要取值),不清楚可以找Man

取值 描述
POLLIN 数据可读(普通数据和优先级数据)
POLLOUT 数据可写(普通数据和优先级数据)
POLLERR 错误
  • 3.socket就绪条件

  • 读就绪

  • sochet内核中,接收缓冲区中的字节数,大于等于低水位标记SO_RECVLOWAT,此时可以无阻塞的读该文件描述符,并且返回值大于0

  • socket TCP通信中,对端关闭连接,此时对该socket读,则返回0 监听的socket上有新的连接请求时

  • socket上有未处理的错误时

  • 写就绪

  • socket内核中,发送缓冲区中的可用字节数(发送缓冲区的空闲位置大小),大于等于低水位标记,SO_SNDLOWAT,此时可以无阻塞的写,并且返回值大于0

  • socket的写操作被关闭(close或者shutdown),对于一个写操作被关闭的socket进行写操作,会触发SIGPIPE信号

  • socket使用非阻塞connect连接成功或失败之后 socket上有未读取的错误

  • 异常就绪

  • socket上收到带外数据(关于带外数据,和TCP紧急模式相关,在TCP报头中有一个紧急指针的字段)

  • 4.poll的优点及缺点

poll的优点

  • 不同与select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现.pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式. 接口使用比 select更方便.
  • poll并没有最大数量限制 (但是数量过大后性能也是会下降).

poll的缺点

  • poll中监听的文件描述符数目增多时 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符.
  • 每次调用poll都需要把大量的pollfd结构从用户态拷贝到内核中. 同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长, 其效 率也会线性下降
  • 5.基于poll实现tcp服务器(多用户)
#pragma once
#include <functional>
#include "tcp_socket.hpp"
#include <poll.h>
#include <unistd.h>
#include <cstring>
#include <vector>
#include <string>
#include <iostream>class Poll
{public:Poll():fds_(nullptr),fds_size_(15),nfds_(0),timeout_(1000){fds_=new pollfd[fds_size_];}bool Add(TcpSocket& sock){if(nfds_== fds_size_){//需要扩容pollfd* new_fds = new pollfd[2 * fds_size_];memcpy(new_fds,fds_,fds_size_ * sizeof(pollfd));fds_size_ *= 2;delete[] fds_;fds_ = new_fds;}fds_[nfds_].fd = sock.GetFd();fds_[nfds_].events = POLLIN;++nfds_;return true;}bool Del(TcpSocket& sock){int del_fd = sock.GetFd();for(size_t i = 0;i < nfds_;++i){//在fds_内才移除if(fds_[i].fd == del_fd){fds_[i] = fds_[--nfds_];break;}}return true;}bool Wait(std::vector<TcpSocket>& list,int timeout = 1000){timeout_=timeout;int ret = poll(fds_,nfds_,timeout_);if(ret < 0){perror("Poll Wait");return false;}else if(ret == 0){std::cout<<"poll wait timeout"<<std::endl;return false;}for(nfds_t i = 0;i < nfds_;++i){if(fds_[i].revents == POLLIN){TcpSocket sock(fds_[i].fd);list.push_back(sock);}}return true;}int GetNfds(){return nfds_;}const pollfd* GetFds(){return fds_;}private:pollfd* fds_;nfds_t fds_size_;nfds_t nfds_;int timeout_;
};typedef std::function<void(const std::string& req,std::string* resp)> Handler;class TcpPollServer
{public:TcpPollServer(const std::string& ip,const uint16_t port):ip(ip),port(port){}~TcpPollServer(){_sock.Close();}bool Start(Handler handler){if(!_sock.Socket())return false;if(!_sock.Bind(ip,port))return false;if(!_sock.Listen())return false;Poll poll;poll.Add(_sock);while(1){std::vector<TcpSocket> list;if(!poll.Wait(list))continue;for(size_t i = 0;i < list.size();++i){if(list[i].GetFd() == _sock.GetFd()){TcpSocket NewSock;if(!_sock.Accept(&NewSock,NULL,NULL))continue;printf("客户端已连接!~\n");poll.Add(NewSock);}else{std::string req;int n = list[i].Recv(&req);if(n == 0){poll.Del(list[i]);list[i].Close();continue;}else{std::cout<<"客户端发送:"<<req<<std::endl;std::string resp;handler(req,&resp);list[i].Send(resp);}}}}return true;}private:TcpSocket _sock;std::string ip;uint16_t port;
};

IO多路转接之poll相关推荐

  1. 网络编程(三)TCP IO多路转接服务器编程(select)

    同系列文章: 1, 文章目录 一,select知识引入 二,select基本概念 2.1 select概念理解前先总结一下通信过程(便于后文理解select) 2.2 select函数的用法 2.2. ...

  2. epoll(eventpoll)是干嘛的?IO多路转接技术(相较select、poll的优点)

    首先我们要知道epoll是用来干什么的(定义):epoll是一种IO多路转接技术,在LINUX网络编程中,经常用来做事件触发,即当有特定事件到来时,能够检测到,而不必阻塞进行监听,基于事件驱动的IO多 ...

  3. IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)

    IO多路转接模型:select/poll/epoll 对大量描述符进行事件监控(可读/可写/异常) select模型 用户定义描述符的事件监控集合 fd_set(这是一个位图,用于存储要监控的描述符) ...

  4. IO多路转接 ——— select、poll、epoll

    文章目录 I/O多路转接之select select初识 select函数 socket就绪条件 select基本工作流程 select服务器 select的优点 select的缺点 select的适 ...

  5. select poll epoll 高效IO 多路转接

    目录 五种常见IO模型 高效IO的概念 阻塞 vs 非阻塞 非阻塞IO fcntl函数 I/O多路转接之select 初识select select函数原型 select操作接口 tcp_server ...

  6. IO多路转接之epoll

    IO多路转接之epoll 文章目录 IO多路转接之epoll 一.epool 二.基于epoll实现服务器(LT) 三.**基于epoll实现服务器(LT)** 一.epool 是为处理大批量句柄而作 ...

  7. 高级IO--1 ---(五种典型IO,阻塞IO,非阻塞IO,信号驱动IO,异步IO, IO多路转接)

    高级IO: 五种典型IO: 阻塞IO/非阻塞IO/信号驱动IO/异步IO/IO多路转接 IO多路转接模型:select/poll/epoll 五种典型IO 阻塞IO IO操作的流程:等待IO操作条件具 ...

  8. IO多路转接模型-----epoll

    epoll: Linux下性能最高的多路转接模型 epoll 有3个相关的系统调用. epoll_create 功能:创建epoll,在内核中创建eventpoll结构体,size决定了epoll最多 ...

  9. 高级IO(多路转接之select、poll、epoll->核反应堆模式)

    ꧁ 大家好,我是 兔7 ,一位努力学习C++的博主~ ꧂ ☙ 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步❧

最新文章

  1. python进程间通信 listener_python进程间通信之Queue
  2. 优秀的程序员都在哪里 如何寻找优秀的程序员?
  3. video processing on Mac and iOS
  4. 手把手带你入门 Spring Security!
  5. 可以与空间耦合的神经网络分子微扰模型BeO
  6. Hadoop:The Definitive Guid 总结 Chapter 1~2 初识Hadoop、MapReduce
  7. 解决vc2008 utf8中文字符串报错 C2001常量中有换行符
  8. 电子科大电气工程导师介绍绍_电子科技大学计算机科学与工程学院研究生导师介绍:葛树志...
  9. 第 8 章 MybatisPlus 扩展
  10. Ubuntu Server 16.04 安装并用两块硬盘做RAID1
  11. php mysql 拖拉 报表_php+mysql 生成统计报表
  12. 开关灯问题 BulbSwitch
  13. Gpower CMS/模板置标
  14. 检索 COM 类工厂中 CLSID 为 {xxx} 的组件失败,原因是出现以下错误: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。...
  15. C语言学习教程二C语言初探
  16. 一个农村孩子的大城市梦想之深入江湖!
  17. 数字图像处理与Python实现笔记之图像压缩
  18. 升级mac最新系统macOS Catalina 10.15
  19. 路由追踪traceroute分析
  20. 【面试题】MyBatis面试题

热门文章

  1. 代画PCB及C语言编程
  2. 调用远程service aidl接口定义
  3. kickstart 安装CentOS GPT分区的完整ks示例
  4. 处理浏览器兼容你最喜欢用哪种方式
  5. 改变软件开发者的形象,增加多样性
  6. 去掉登陆下的“扫一扫,访问微社区
  7. 常用 API 函数(3): 文件处理函数
  8. LELE的RPG难题
  9. CCNA学习指南第二章
  10. 冒泡排序、选择排序和插入