首页 > 技术 > epoll入门实例

epoll入门实例

2016年4月10日 发表评论 阅读评论

epoll是目前进行服务器端编程的普遍选择,好处很多,这里不再赘述,本文主要描述如何在c语言中使用epoll的完整样例程序。
首先介绍用到的数据结构和三个api说明,然后通过编写一个打印所有输入到socket的字符输出到终端的服务器端的程序来完成整个例子。

epoll_event是用来对要监控的socket描述, 它包括epoll_data_t和要监控的事件类型的(一个__uint32_t类型的events)。epoll_data_t里的fd是用来存储要监控的文件描述符。

events 结构体中第一个参数支持的事件类型

– EPOLLIN,读事件

– EPOLLOUT,写事件

– EPOLLPRI,带外数据,与select的异常事件集合对应

– EPOLLRDHUP,TCP连接对端至少写写半关闭

– EPOLLERR,错误事件

– EPOLLET,设置事件为边沿触发

– EPOLLONESHOT,只触发一次,事件自动被删除

epoll在一个文件描述符上只能有一个事件,在一个描述符上添加多个事件,会产生EEXIST的错误。同样,删除epoll的事件,只需描述符就够了

使用epoll的三个api
头文件 /usr/include/sys/epoll.h
1. 生成一个epoll专用的文件描述符
如果调用成功返回0,不成功返回-1

epoll_create返回的是一个文件描述符,也就是说epoll是以特殊文件的方式体现给用户
__size提示操作系统,用户可能要使用多少个文件描述符,该参数已经废弃,填写一个大于0的正整数

2.用于控制某个文件描述符上的事件,可以注册事件,修改事件,删除事件。
如果调用成功返回0,不成功返回-1

3.用于轮询I/O事件的发生,返回发生事件数

epoll的api使用方式
1.epoll_create 生成的epoll专用的文件描述符
2.使用epoll_ctl注册事件,修改事件,删除事件对应的文件描述符到epollfd指定的epoll内核事件表中
3.使用epoll_wait阻塞等待注册的文件描述符上可读事件的发生
4.当有新客户端的连接或者客户端的数据写入,返回需要处理的事件数目

epoll的两种模式

1. 水平触发(LT):使用此种模式,当数据可读的时候,epoll_wait()将会一直返回就绪事件。如果你没有处理完全部数据,并且再次在该epoll实例上调用epoll_wait()才监听描述符的时候,它将会再次返回就绪事件,因为有数据可读。ET只支持非阻塞socket。

2. 边缘触发(ET):使用此种模式,只能获取一次就绪通知,如果没有处理完全部数据,并且再次调用epoll_wait()的时候,它将会阻塞,因为就绪事件已经释放出来了。

ET的效能更高,但是对程序员的要求也更高。在ET模式下,我们必须一次干净而彻底地处理完所有事件。LT两种模式的socket都支持。

实例代码

1.创建并绑定服务器端socket
采用一种可移植的方式来生产socket,getaddrinfo返回对应的网卡信息,遍历对应的网络接口生成socket
成功返回socket文件描述符,失败返回-1

2.设置socket为非阻塞模式
通过在文件描述符上设置 O_NONBLOCK 表识来实现非阻塞socket

3.event 循环处理

main函数的流程是
1. create_and_bind创建服务器端的socket描述符
2. 设置描述符为非阻塞
3. 监听描述符
4. 创建epoll文件描述符efd
5. 使用边缘触发的方式添加sfd输入监听事件

最外层的while循环时主事件循环(event loop)。调用epoll_wait阻塞等待事件发生,当事件到达epoll_wait返回事件在事件参数中,一批epoll_event结构体。
epoll事件循环中epoll实例在建立新连接时候添加事件和当断开连接的时候删除事件。

当事件发生时,有如下几种方式
错误:当发生错误,或者不是可读事件通知时,简单关闭文件描述符,关闭文件描述符会自动从efd的监控集中删除。
新连接:当监听描述符可读时,表示有新的连接到达,accept()新连接,设置新连接描述符为非阻塞并添加到efd监控集中。
客户端数据:当任何一个客户端文件描述符可读,使用read()每次读区512字节循环读取。 因为我们需要读取当前所有可读区数据 ,当边缘触发的情况下不会再次通知可读。 读取到的数据调用write写到标准输出stdout (fd=1)。如果read(2)返回0,表示EOF并切可以关闭客户端连接。如果返回-1并且 errno设置为EAGAIN表示这个事件所有可读的数据读取完毕可以返回进入主事件循环。

就这样不断的循环,添加和删除文件描述符到efd的监控集中。
https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c/

分类: 技术 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.