最近在写Swoole
的Coroutine::Socket::readv
功能的时候,遇到了一个处理连接关闭的细节问题。
一般情况下,当本端主动关闭连接之后,会触发EPOLLIN
和EPOLLHUP
事件,然后当本端调用recv
的时候,返回值会是0
,那么,本端就会进行一些清理连接和内存的操作。但是,不是所有的情况都是如此,如果仅仅依赖于这个recv
的返回值来判断连接是否断了,那么可能会有一些问题。在alpine
上面,收到EPOLLHUP
事件之后,调用recv
得到的一个EAGAIN
错误。那么,如果我们仅仅是判断recv
返回了EAGAIN
,那么,我们接下来就会直接回到事件循环。并且,这个EAGAIN
是持续的,这就导致了死循环了。
所以,我们需要对EPOLLHUP
事件进行一次判断,来确定连接有没有关闭,如果得到了EPOLLHUP
事件,那么我们就需要进行连接的清理工作了。