多路I/O转接技术
借助LINUX内核来注册监听的文件描述符,文件描述符有相应的请求先经过内核处理之后,再由用户的应用来对请求做出相应的回复,大大的提高了程序的运行效率。
与多进程/多线程相比:无需阻塞等待连接,在有数据的时候直接读取\处理数据,更加高效
抽象原理图
声明:因个人能力有限,本文仅是个人的学习记录笔记,有错误之处还望指出
多路IO转接实现的3种方式
函数原型
select函数
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
- 参数1:所监听的文件描述符中,最大的文件描述符+1
- 参数2:可读事件集合
- 参数3:可写事件集合
- 参数4:异常事件集合
- 参数5:指定连接时间(默认可设置为NULL)
对集合的操作相关函数
- void FD_ZERO(fd_set *set);集合清空
- void FD_CLR(int fd, fd_set *set);将fd从集合set中清除
- int FD_ISSET(int fd, fd_set *set);判断fd是否在set集合中
- void FD_SET(int fd, fd_set *set);设置fd到set集合中
select函数的缺陷
- 监听的文件描述符有限 FD_SETSIZE(1024)
- 监听的集合是传入传出参数 要用两个集合来保存前后的集合
- 满足的集合要以此判断是否是相应的事件(读/写/异常) 用自定义数组实现,但是效率低下
案例要求
- 实现与多个服务器的连接。
- 将客户端的小写转化为大写。
poll函数
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
struct timespec {
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
- 参数1: pollfd结构体的数组,里面封装了文件描述符,请求事件和返回事件
请求事件/返回事件的参数:POLLIN,POLLOUT,POLLHUP,POLLERR,POLLNVAL
-
参数2:监听的最大上限+1
-
参数3:等待连接的时间(单位:毫秒)
poll代码实现epoll函数
而塞过 2021-1-11
关于我:一个就要进入互联网,经历社会毒打的99小伙