非阻塞tcp与epoll连接

时间:2010-05-20 15:04:35

标签: linux tcp epoll

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

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

2 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:4)

以下是non-blocking tcp connect()的一些很好的信息。

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

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

相关问题