https://blog.csdn.net/lihao21/article/details/67631516
http://blog.lucode.net/linux/epoll-tutorial.html
typedef union epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; struct epoll_event { __uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ };
其中,data是一个联合体,能够存储fd或其它数据,我们需要根据自己的需求定制。events表示监控的事件的集合,是一个状态值,通过状态位来表示,可以设置如下事件:
- EPOLLERR : 文件上发上了一个错误。这个事件是一直监控的,即使没有明确指定
- EPOLLHUP : 文件被挂断。这个事件是一直监控的,即使没有明确指定
- EPOLLRDHUP : 对端关闭连接或者shutdown写入半连接
- EPOLLET : 开启边缘触发,默认的是水平触发,所以我们并未看到EPOLLLT
- EPOLLONESHOT : 一个事件发生并读取后,文件自动不再监控
- EPOLLIN : 文件可读
- EPOLLPRI : 文件有紧急数据可读
- EPOLLOUT : 文件可写
- EPOLLWAKEUP : 如果EPOLLONESHOT和EPOLLET清除了,并且进程拥有CAP_BLOCK_SUSPEND权限,那么这个标志能够保证事件在挂起或者处理的时候,系统不会挂起或休眠
注意一下,EPOLLHUP并不代表对端结束了连接,这一点需要和EPOLLRDHUP区分。通常情况下EPOLLHUP表示的是本端挂断,造成这种事件出现的原因有很多,其中一种便是出现错误,更加细致的应该是和RST联系在一起,不过目前相关文档并不是很全面,本文会进一步跟进。
- 联合体data中的那个ptr是很有用的,只不过这就意味着你将该对象的生命周期交给了epoll,不排除会有潜在bug的影响,需要辅以timeout
ncat命令进行测试
$ ncat 127.0.0.1 8000
http://blog.chinaunix.net/uid/28541347/sid-193117-list-1.html
水平触发
1. 对于读操作
只要缓冲内容不为空,LT模式返回读就绪。
2. 对于写操作
只要缓冲区还不满,LT模式会返回写就绪。
边缘触发
1. 对于读操作
(1)当缓冲区由不可读变为可读的时候,即缓冲区由空变为不空的时候。
(2)当有新数据到达时,即缓冲区中的待读数据变多的时候。
(3)当缓冲区有数据可读,且应用进程对相应的描述符进行EPOLL_CTL_MOD 修改EPOLLIN事件时。
2. 对于写操作
(1)当缓冲区由不可写变为可写时。
(2)当有旧数据被发送走,即缓冲区中的内容变少的时候。
(3)当缓冲区有空间可写,且应用进程对相应的描述符进行EPOLL_CTL_MOD 修改EPOLLOUT事件时。
---------------------