假设本地
linux主机上的TCP套接字与远程主机处于连接状态.本地主机正在使用epoll_wait通知与远程主机的套接字上的事件.
如果远程主机要呼叫:
shutdown(s,SHUT_WR);
在其连接的套接字上表示已经完成传输,在本地主机上将为其套接字epoll_wait返回什么事件?
我假设EPOLLIN将永远得到返回,并且后续的recv调用将返回0,以指示远程端已完成tranmitting.
EPOLLHUP或EPOLLRDHUP怎么样? (这两个事件有什么区别)?
甚至EPOLLERR?
如果远程主机拨打“关闭”而不是“关机”,上述任何一个答案是否会改变?
解决方法
我做了大量的工作后才回答了这个问题.
监听epoll事件的套接字通常会在远程对等体呼叫关闭或关闭(SHUT_WR)时收到EPOLLRDHUP(除了EPOLLIN)事件标志.这不意味着插座已经死了.对recv()的后续调用将返回套接字上的任何未读数据,最终返回“0”表示EOF.如果远程对等体只做了其套接字的一半,甚至可能发回数据.
一个显着的例外是如果远程对等体使用在其套接字上启用的SO_LINGER选项,其余值为“0”.关闭这样的套接字的结果可能会导致TCP RST发送而不是FIN.从我读到的,连接重置事件将产生EPOLLHUP或EPOLLERR. (我没有时间确认,但有道理).
有一些文档建议有较旧的Linux实现不支持EPOLLRDHUP,因此EPOLLHUP将被生成.
而对于什么是值得的,在我特定的情况下,我发现特殊情况EPOLLHUP或EPOLLRDHUP事件的代码并不是太有意思.相反,只需将这些事件与EPOLLIN / EPOLLOUT相同,并根据需要调用recv()(或send()).但是要注意从recv()和send()返回的返回码.