当 epoll 发出 activity 信号时,recv() 调用如何阻塞?

How could a recv() call block when epoll has signalled activity?

我的应用程序类似于 libevent,使用 epoll(在级别触发模式下)检测 I/O activity 并调用回调来处理它。

我最近发现我的 TCP/IP 套接字正在阻塞,这是一个意外,但我仍然不希望 recv() 调用阻塞在 [= 报告的 FD 上12=] 已读取 activity 未决。即使套接字出现错误,recv() 肯定会 return 并告诉我。

我对此有什么误解?
在这种情况下,什么样的网络条件会导致 recv() 阻塞?

如果您使用 Epoll 轮询 EPOLLIN 事件,那么之后的 recv 调用应该会立即 return。此外,我希望您正在使用非阻塞套接字。如果您想查找错误,则可以查找 EPOLLERR 事件。如果套接字在 epoll 发出信号后关闭,则 recv 应该失败。您的 epoll_wait、epoll_ctl 和套接字创建的代码片段将有助于调试问题。

来自Linux select man-page:

Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.

(是的,我知道 epoll() 与 select() 不同,但我怀疑相同的基本条件适用于两者)

我认为如果你真的想避免阻塞,唯一安全的方法是将套接字设置为 non-blocking 模式。