TCP/IP,Linux多路IO模型epoll,select和poll的升级版,有更多的API,消耗更多句柄换来监听的清晰度,select,poll,epoll比较
O、在服务端拥有较多的连接套接字的情况下,只想监听部分套接字,需要用到epoll,
1、和select和poll相比,epoll可以在发生了事件后直接返回发生了事件的描述符,而不用一个个判断。
2、epoll是目前非常常见的多路io转接模型,效率上大于等于select,在多连接和多监听的情况下,二者效率差不多。
3、epoll拥有比select和poll较多的API:
一、epollAPI,创建epoll句柄
创建一个epoll句柄,参数size用来告诉内核监听的文件描述符的个数,和内存大小有关
#include <sys/epoll.h>
int epoll_create(int size);
1、参数size就是监听的数目,但是这是个建议值,后续如果传入10但想要监听50个,也是可以的。
2、epoll句柄指向操作系统中的一个平衡二叉树,每一个受到监听的描述符都是这个二叉树的一个节点。
二、epollAPI,设定监听事件
控制某个epoll监控的文件描述符上的事件:注册、修改、删除
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
1、第一个参数epfd是epoll句柄
2、第二个参数op表示动作,
EPOLL_CTL_ADD:添加描述符节点
EPOLL_CTL_MOD:修改描述符节点
EPOLL_CTL_DEL:删除描述符节点
3、第三个参数fd是进行动作的描述符
4、第四个参数event是事件,
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
typedef union epoll_data {
void *ptr;//泛型指针,可以接受任何类型
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
//注意这里的这个结构是个联合体,只传一个值,就是文件描述符,这也是epoll能返回直接发生事件的描述符的原因。
三、epollAPI,阻塞监听
使用epoll阻塞监听套接字,
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
1、第一个参数是epoll句柄
2、第二个参数是epoll_event结构体的数组
3、第三个参数是events的大小,不能大于创建events时的大小,是结构体数组的最大文件描述符+1,和select传的数值没有区别
4、指定超时时间,-1时阻塞,0时立即返回,>0是指定毫秒