使用 epoll 进行非阻塞 tcp 连接

发布于 2024-09-02 06:11:21 字数 286 浏览 5 评论 0原文

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

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

My linux application is performing non-blocking TCP connect syscall and then use epoll_wait to detect three way handshake completion.
Sometimes epoll_wait returns with both POLLOUT & POLLERR events set for the same socket descriptor.

I would like to understand what's going on at TCP level. I'm not able to reproduce it on demand. My guess is that between two calls to epoll_wait inside my event loop we had a SYN+ACK/ACK/FIN sequence but again I'm not able to reproduce it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷︶言冷语的世界 2024-09-09 06:11:21

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

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

It is likely for this to happen if the connect has failed - for example with "connection timed out" (for sockets doing a non-blocking connect, POLLOUT becomes set when the connect operation has finished for both successful and unsuccessful outcomes).

When POLLOUT becomes set for the socket, use getsockopt(sock, SOL_SOCKET, SO_ERROR, ...) to check if the connect succeeded or not (the SO_ERROR socket option is 0 in this case, and otherwise indicates why the connect failed).

溺深海 2024-09-09 06:11:21

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

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

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

Here is some good information on non-blocking tcp connect().

When a socket error is detected (i.e. connection closed/refused/timedout), epoll will return the registered interest events POLLIN/POLLOUT with POLLERR. So epoll_wait() will return POLLOUT|POLLERR if you registered POLLOUT, or POLLIN|POLLOUT|POLLERR if POLLIN|POLLOUT was registered.

Just because epoll returns POLLIN doesn't mean there will be data available to read, since recv() may just return the error from the non-blocking connect() call. I think epoll returns all the registered events with POLLERR to make sure the program calls send()/recv()/etc.. and gets the socket error. Some programs never check for POLLERR/POLLHUP and only catch socket errors on the next send()/recv() call.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文