根据linux 手册页,
EPOLLHUP
从诸如管道或流套接字的通道读取时,此事件仅表示对等方关闭其通道的末尾.
EPOLLRDHUP
流套接字对等关闭连接,或关闭写入一半的连接.
我几乎无法区分EPOLLHUP和EPOLLRDHUP.
对我来说,无论何时EPOLLRDHUP使用EPOLLHUP都可以使用相同的语义.
我对吗?如果没有,有什么解释吗?
另请参阅此问题,到目前为止尚未回答。
EPOLLHUP即使在man和内核文档中也有很多关于的困惑。人们似乎相信,当一个描述符轮询它返回本地关闭书写,即shutdown(SHUT_WR),即导致相同的呼叫EPOLLRDHUP 在对等。但这是不正确的,在我的实验中,我得到了EPOLLOUT,EPOLLHUP之后没有得到shutdown(SHUT_WR)(是的,变得可写是违反直觉的,因为写作的一半是封闭的,但这不是问题的重点)。
这个人很穷,因为它EPOLLHUP说到挂起发生在关联的文件描述符上时,而没有说“挂断”是什么意思-对方做了什么?发送了什么数据包?另一篇文章只是使事情更加混乱,对我来说似乎是完全错误的。
我的实验表明,EPOLLHUP一旦双向交换EOF(FIN数据包),即双方都发出,就到达了shutdown(SHUT_WR)。它与无关SHUT_RD,我从不称呼它。也与无关close。在数据包方面,我怀疑EPOLLHUP主机发送的FIN会引起确认,即终止发起方在4向关机握手的第3步中引发此事件,而对等方在第4步中引发(请参见此处))。如果得到确认,那就太好了,因为它填补了我一直在寻找的空白,即如何在不使用LINGER的情况下轮询非阻塞套接字以获得最终的确认。它是否正确?
(注意:我正在使用ET,但我认为与此无关)
该代码在一个框架之中,我提取它的肉,用之外TcpSocket::createListener,TcpSocket::connect和TcpSocket::accept,它做你所期望(这里没有显示)。
void registerFd(int pollFd, int fd, const char* description)
{
epoll_event ev = {
EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET,
const_cast<char*>(description) // union aggregate initialisation, initialises …Run Code Online (Sandbox Code Playgroud)