5

我的 linux 应用程序正在执行非阻塞 TCP 连接系统调用,然后用于epoll_wait检测三向握手完成。有时epoll_wait返回同时为同一个套接字描述符设置的POLLOUT&事件。POLLERR

我想了解 TCP 级别发生了什么。我无法按需复制它。我的猜测是,在我的事件循环内部的两次调用之间,epoll_wait我们有一个 SYN+ACK/ACK/FIN 序列,但我再次无法重现它。

4

2 回答 2

6

如果连接失败,则可能会发生这种情况 - 例如“连接超时”(对于执行非阻塞连接的套接字,POLLOUT在连接操作完成时设置成功和不成功的结果)。

POLLOUT为套接字设置时,用于getsockopt(sock, SOL_SOCKET, SO_ERROR, ...)检查连接是否成功(SO_ERROR在这种情况下套接字选项为0,否则指示连接失败的原因)。

于 2010-05-21T01:17:47.503 回答
4

这是关于非阻塞 tcp connect()的一些很好的信息。

当检测到套接字错误(即连接关闭/拒绝/超时)时,epoll 将返回注册的兴趣事件 POLLIN/POLLOUT 和 POLLERR。因此,如果您注册了 POLLOUT,epoll_wait() 将返回 POLLOUT|POLLERR,如果注册了 POLLIN|POLLOUT,则返回 POLLIN|POLLOUT|POLLERR。

仅仅因为 epoll 返回 POLLIN 并不意味着会有数据可供读取,因为 recv() 可能只是从非阻塞 connect() 调用返回错误。我认为 epoll 使用 POLLERR 返回所有已注册的事件,以确保程序调用 send()/recv()/etc.. 并获取套接字错误。有些程序从不检查 POLLERR/POLLHUP 并且只在下一次 send()/recv() 调用时捕获套接字错误。

于 2010-11-10T23:25:21.163 回答