sel*_*bie 11 sockets linux epoll tcp
假设本地linux主机上的TCP套接字与远程主机处于连接状态.本地主机正在使用epoll_wait通知远程主机的套接字上的事件.
如果远程主机要打电话:
shutdown(s,SHUT_WR);
Run Code Online (Sandbox Code Playgroud)
在其连接的套接字上,表明它已完成传输,epoll_wait将在本地主机上为其套接字返回什么事件?
我假设总是会返回EPOLLIN并且后续的recv调用将返回0以指示远程端已完成传输.
EPOLLHUP或EPOLLRDHUP怎么样?(这两个事件有什么区别)?
甚至EPOLLERR?
如果远程主机呼叫"关闭"而不是"关闭",上述任何一个的答案是否会改变?
sel*_*bie 20
我在做了繁重的工作后自己回答这个问题才找到答案.
侦听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()返回的返回码.