epoll开发建议说明

  • Post author:
  • Post category:其他



2.。。



1、listen fd,有新连接请求,

对端发送普通数据

触发EPOLLIN。


2、带外数据,只触发EPOLLPRI。


3、对端正常关闭(程序里close(),shell下kill或ctr+c),触发EPOLLIN和EPOLLRDHUP,但是不触发EPOLLERR 和EPOLLHUP。


再man epoll_ctl看下后两个事件的说明,这两个应该是本端(server端)出错才触发的。


5、对端异常断开连接(只测了拔网线),没触发任何事件。




附man:


EPOLLIN       连接到达;有数据来临;


The associated file is available for read(2) operations.


EPOLLOUT      有数据要写


The associated file is available for write(2) operations.


EPOLLRDHUP    这个好像有些系统检测不到,可以使用EPOLLIN,read返回0,删除掉事件,关闭close(fd);


如果有EPOLLRDHUP,检测它就可以直到是对方关闭;否则就用上面方法。


Stream socket peer closed connection, or shut down writing half


of connection. (This flag is especially useful for writing sim-


ple code to detect peer shutdown when using Edge Triggered moni-


toring.)


EPOLLPRI      外带数据


There is urgent data available for read(2) operations.




EPOLLERR      只有采取动作时,才能知道是否对方异常。即对方突然断掉,是不可能


有此事件发生的。只有自己采取动作(当然自己此刻也不知道),read,write时,出EPOLLERR错,说明对方已经异常断开。




EPOLLERR 是服务器这边出错(自己出错当然能检测到,对方出错你咋能知道啊)





关于 EPOLLERR:


socket能检测到对方出错吗?目前为止,好像我还不知道如何检测。


但是,在给已经关闭的socket写时,会发生EPOLLERR,也就是说,只有在采取行动(比如


读一个已经关闭的socket,或者写一个已经关闭的socket)时候,才知道对方是否关闭了。


这个时候,如果对方异常关闭了,则会出现EPOLLERR,出现Error把对方DEL掉,close就可以


了。

3.各类事件


1)监听的fd,此fd的设置等待事件:


EPOLLIN ;或者EPOLLET |EPOLLIN


由于此socket只监听有无连接,谈不上写和其他操作。


故只有这两类。(默认是LT模式,即EPOLLLT |EPOLLIN)。




说明:如果在这个socket上也设置EPOLLOUT等,也不会出错,


只是这个socket不会收到这样的消息。




2)客户端正常关闭


client 端close()联接


server 会报某个sockfd可读,即epollin来临。


然后recv一下 , 如果返回0再掉用epoll_ctl 中的EPOLL_CTL_DEL , 同时close(sockfd)。


有些系统会收到一个EPOLLRDHUP,当然检测这个是最好不过了。只可惜是有些系统,


上面的方法最保险;如果能加上对EPOLLRDHUP的处理那就是万能的了。




3)客户端异常关闭:




客户端异常关闭,并不会通知服务器(如果会通知,以前的socket当然会有与此相关


的api)。正常关闭时read到0后,异常断开时检测不到的。服务器再给一个已经关闭


的socket写数据时,会出错,这时候,服务器才明白对方可能已经异常断开了(读也


可以)。




Epoll中就是向已经断开的socket写或者读,会发生EPollErr,即表明已经断开。




4)EpollIn:




5)监听的skocket只需要EpollIn就足够了,EpollErr和EpollHup会自动加上。


监听的socket又不会写,一个EpollIn足矣。




4. 补充 EpollErr


当客户端的机器在发送“请求”前,就崩溃了(或者网络断掉了),则服务器一端是无从知晓的。


按照你现在的这个“请求响应方式”,无论是否使用epoll,都必须要做超时检查。


因此,这个问题与epoll无关。EpollErr这种错误必须是有动作才能检测出来。


服务器不可能经常的向客户端写一个东西,依照有没有EpollErr来判断客户端是不是死了。


因此,服务器中的超时检查是很重要的。这也是以前服务器中作死后确认的原因。


新的代码里也是时间循环,时间循环….


!!!服务器 中的超时检查!!!很重要