EPOLLRDHUP 不可靠 [英] EPOLLRDHUP not reliable
问题描述
我正在使用 epoll_wait
通过客户端-服务器 TCP 连接使用非阻塞读/写.
I'm using non-blocking read/writes over a client-server TCP connection with epoll_wait
.
问题是,我无法使用 EPOLLRDHUP
标志可靠地检测到对等关闭连接"事件.经常发生标志未设置的情况.客户端使用 close()
并且服务器在大多数情况下从 epoll_wait
接收一个 EPOLLIN |EPOLLRDHUP
事件.正如预期的那样,读取产生零字节.但是,有时只有 EPOLLIN
出现,产生零字节.
Problem is, I can't reliably detect 'peer closed connection' event using the EPOLLRDHUP
flag. It often happens that the flag is not set. The client uses close()
and the server, most of the time, receives, from epoll_wait
, an EPOLLIN | EPOLLRDHUP
event. Reading yields zero bytes, as expected. Sometimes, though, only EPOLLIN
comes, yielding zero bytes.
使用 tcpdump
的调查表明,据我所知,正常关闭发生了.我看到一个 Flags [F.], Flags [F.], Flags [.]
事件序列,它应该对应于 FIN、FIN 和 ACK.SO_LINGER
没有被使用.
Investigation using tcpdump
shows that normal shutdown occurs as far as I can tell. I see a Flags [F.], Flags [F.], Flags [.]
sequence of events, which should correspond to FIN, FIN and ACK. SO_LINGER
is nowhere used.
我考虑过在零字节读取时处理对等关闭",但是,您可能会得到一个 EPOLLIN |具有非零字节可用的 EPOLLRDHUP
事件,当对等方发送 &立即关闭连接 - 在我需要基于 EPOLLRDHUP
的情况下.建议?
I considered handling 'peer closed' on zero-byte read, however, there is the possibility that you get an EPOLLIN | EPOLLRDHUP
event with non-zero bytes available, when the peer sends & immediately closes the connection - case in which I need to base myself on the EPOLLRDHUP
. Suggestions?
推荐答案
要回答这个问题:EPOLLRDHUP
如果您在收到零字节读取后继续轮询,确实会出现.所以从我的实验来看,无论是零字节读取的 EPOLLIN
还是 EPOLLRDHUP
都是有序关闭的可靠指标,唯一的问题是,它们没有一起接收.有时(成为这个问题的主题的情况),碰巧收到 EPOLLIN,产生零字节(连接终止),在随后的轮询中,您会看到 EPOLLRDHUP
.其他时候,反之亦然:您将 EPOLLRDHUP
与一个 EPOLLIN
一起获得,后者表示要读取的实际字节.然后,在后续读取中,您将获得零字节.
To answer this: EPOLLRDHUP
indeed comes if you continue to poll after receiving a zero-byte read.
So from my experiments it looks like either an EPOLLIN
with zero-byte read or an EPOLLRDHUP
are reliable indicators for orderly shutdown, the only trouble was, they are not received together. Sometimes (the case that makes the subject of this question), it happens that EPOLLIN is received, yielding zero bytes (connection terminated), and on subsequent polling you get to see the EPOLLRDHUP
. Other times, it's vice-versa: you get the EPOLLRDHUP
together with an EPOLLIN
that signals actual bytes to be read. Then, on subsequent reads, you get zero bytes.
这篇关于EPOLLRDHUP 不可靠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!