【问题标题】:How do I use EPOLLHUP如何使用 EPOLLHUP
【发布时间】:2011-09-20 05:46:31
【问题描述】:

你们能否为我提供一个使用 EPOLLHUP 处理死节点的良好示例代码?我知道这是检测用户断开连接的信号,但不确定如何在代码中使用它..提前谢谢..

【问题讨论】:

  • (冒昧添加了 epoll 和 linux 标签,因为 Q 与此有关)

标签: linux networking epoll


【解决方案1】:

您使用EPOLLRDHUP 来检测对等关闭,而不是EPOLLHUP(它表示套接字意外关闭,即通常是内部错误)。

使用它非常简单,只需将标志与您提供给epoll_ctl 的任何其他标志一起“或”。因此,例如,而不是 EPOLLIN 写 EPOLLIN|EPOLLRDHUP。

在epoll_wait 之后,执行if(my_event.events & EPOLLRDHUP),然后在对方关闭连接时执行任何您想要执行的操作(您可能想要关闭套接字)。

请注意,从套接字读取时获得“零字节读取”结果也意味着另一端已关闭连接,因此您也应始终检查这一点,以避免令人讨厌的意外(FIN 可能会在您从EPOLLIN 醒来后到达,但在您调用read 之前,如果您处于 ET 模式,您将无法获得另一个通知)。

【讨论】:

  • 感谢您的友好回答。我很难找到关于高级网络的好的参考资料。所有在线教程或示例仅涵盖基本内容,并未涵盖任何错误处理。您能否告诉我任何好的参考资料或教程或与高级网络相关的任何内容,包括书籍?提前致谢。
  • Damon,您能否详细说明“read() 返回零”的情况? [我指的是最后一段。] 订阅了 EPOLLRDHUP 后,当对等端关闭连接时,此标志将始终在 epoll_wait() 中设置。嗯,这正是它的目的!如果在关闭的情况下没有设置 EPOLLRDHUP,那显然是一个内核错误。因此,可以肯定地说,当 read() 返回 0 时设置了 EPOLLRDHUP 或 EPOLLHUP 或 EPOLLERR。在我的测试中,我无法模拟您的假设,坦率地说,这是我第一次听说它。您是否有任何其他信息或至少
  • 理论上你是对的。理论上,当read 将返回“读取零字节”时,必须已经设置了EPOLLRDHUP。在实践中,我看到在边缘触发模式下发生了奇怪的事情(据我所知,水平触发在各方面都是 100% 可靠的),这与文档所说的也不完全一致。因此,为了 100% 安全,在边沿触发模式下,我会检查 read 是否返回“零读取”,只是为了确定。它并没有真正花费任何成本,它让您处于 100% 的故障安全位置。
  • 举一个我认为不正确的“奇怪行为”的例子,应该通知几个在同一个描述符上等待的 epoll,如果发生某些事情,应该在同一个 epoll 上阻塞的几个线程都被唤醒描述符上。这就是第二节的 Q+A。 7手册页说。我认为这将是在同一台机器上及时同步多个线程的一种很酷的方法。除了,在 ET 中,它会唤醒一个线程,仅此而已。如果线程在事件发生后进入等待状态(因为它已经被消耗),则行为会正常,但在每种情况下都会发生。
  • 仅供参考,EPOLLRDHUP 可能不会与对应于零大小读取的 EPOLLIN 一起设置,即使对于级别触发的 epoll。我经常在我的 linux 上看到这个。但是,如果您继续轮询,您将得到它(连同一个 EPOLLIN 和一个零大小的读取)。我也知道可能会发生相反的情况,即,如果对等方在关闭连接之前发送了某些内容,则将 EPOLLRDHUP 与 EPOLLIN 一起获得非零读取。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
相关资源
最近更新 更多