IO多路转接之poll
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相关推荐
- 网络编程(三)TCP IO多路转接服务器编程(select)
同系列文章: 1, 文章目录 一,select知识引入 二,select基本概念 2.1 select概念理解前先总结一下通信过程(便于后文理解select) 2.2 select函数的用法 2.2. ...
- epoll(eventpoll)是干嘛的?IO多路转接技术(相较select、poll的优点)
首先我们要知道epoll是用来干什么的(定义):epoll是一种IO多路转接技术,在LINUX网络编程中,经常用来做事件触发,即当有特定事件到来时,能够检测到,而不必阻塞进行监听,基于事件驱动的IO多 ...
- IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)
IO多路转接模型:select/poll/epoll 对大量描述符进行事件监控(可读/可写/异常) select模型 用户定义描述符的事件监控集合 fd_set(这是一个位图,用于存储要监控的描述符) ...
- IO多路转接 ——— select、poll、epoll
文章目录 I/O多路转接之select select初识 select函数 socket就绪条件 select基本工作流程 select服务器 select的优点 select的缺点 select的适 ...
- select poll epoll 高效IO 多路转接
目录 五种常见IO模型 高效IO的概念 阻塞 vs 非阻塞 非阻塞IO fcntl函数 I/O多路转接之select 初识select select函数原型 select操作接口 tcp_server ...
- IO多路转接之epoll
IO多路转接之epoll 文章目录 IO多路转接之epoll 一.epool 二.基于epoll实现服务器(LT) 三.**基于epoll实现服务器(LT)** 一.epool 是为处理大批量句柄而作 ...
- 高级IO--1 ---(五种典型IO,阻塞IO,非阻塞IO,信号驱动IO,异步IO, IO多路转接)
高级IO: 五种典型IO: 阻塞IO/非阻塞IO/信号驱动IO/异步IO/IO多路转接 IO多路转接模型:select/poll/epoll 五种典型IO 阻塞IO IO操作的流程:等待IO操作条件具 ...
- IO多路转接模型-----epoll
epoll: Linux下性能最高的多路转接模型 epoll 有3个相关的系统调用. epoll_create 功能:创建epoll,在内核中创建eventpoll结构体,size决定了epoll最多 ...
- 高级IO(多路转接之select、poll、epoll->核反应堆模式)
꧁ 大家好,我是 兔7 ,一位努力学习C++的博主~ ꧂ ☙ 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步❧
最新文章
- python进程间通信 listener_python进程间通信之Queue
- 优秀的程序员都在哪里 如何寻找优秀的程序员?
- video processing on Mac and iOS
- 手把手带你入门 Spring Security!
- 可以与空间耦合的神经网络分子微扰模型BeO
- Hadoop:The Definitive Guid 总结 Chapter 1~2 初识Hadoop、MapReduce
- 解决vc2008 utf8中文字符串报错 C2001常量中有换行符
- 电子科大电气工程导师介绍绍_电子科技大学计算机科学与工程学院研究生导师介绍:葛树志...
- 第 8 章 MybatisPlus 扩展
- Ubuntu Server 16.04 安装并用两块硬盘做RAID1
- php mysql 拖拉 报表_php+mysql 生成统计报表
- 开关灯问题 BulbSwitch
- Gpower CMS/模板置标
- 检索 COM 类工厂中 CLSID 为 {xxx} 的组件失败,原因是出现以下错误: 8000401a 因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码。...
- C语言学习教程二C语言初探
- 一个农村孩子的大城市梦想之深入江湖!
- 数字图像处理与Python实现笔记之图像压缩
- 升级mac最新系统macOS Catalina 10.15
- 路由追踪traceroute分析
- 【面试题】MyBatis面试题