首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么构成“可读”(kqueue/epoll)

什么构成“可读”(kqueue/epoll)
EN

Stack Overflow用户
提问于 2013-10-29 17:54:42
回答 4查看 563关注 0票数 0

我知道,如果远程主机优雅地关闭连接,epoll将报告EPOLLIN,调用readrecv不会阻塞,并返回0字节(即流结束)。

但是,如果连接没有很好地关闭,并且writesend操作失败,这是否会导致epoll随后为该套接字返回EPOLLIN,从而产生相同/类似的流场景?

我试图找到关于这种行为的文档,但是没有成功,虽然我可以对它进行测试,但我不感兴趣的是在特定的发行版上使用特定的内核版本会发生什么。

EN

回答 4

Stack Overflow用户

发布于 2013-11-17 00:43:47

从规范中确实不是很明显,但它适用于poll()

  • 如果有可读取的数据,即使连接关闭,也会返回POLLIN
  • 如果由于关闭的连接而无法读写,则返回POLLHUPPOLLERR
  • 如果不再可能阅读,但写入(例如,另一方执行shutdown(SHUT_WR)),则返回POLLIN,而不返回POLLHUPPOLLERR。(这允许正常地等待POLLOUT。)

只要设置了POLLINPOLLHUPPOLLERR,就可以尝试读取。

kqueue()中,可能会触发一个EVFILT_READ过滤器。这将在手册页中描述,并且应该足够清楚。

请注意,如果您不启用TCP驻留(默认情况下,FreeBSD启用它们,但大多数其他操作系统不启用),如果网络以某些方式中断,等待读取数据可能会永远停滞不前。即使TCP保持生命是打开的,它往往需要几个小时才能检测到一个断开的连接。

票数 2
EN

Stack Overflow用户

发布于 2013-10-29 18:15:07

当对等机意外关闭时,它可能不会返回EPOLLIN。在过去,我通过VirtualBox将这种现象描述为以下步骤:

  1. 在一个VM上启动服务器。
  2. 在另一个VM上启动客户端,连接服务器并保持连接而不执行任何操作。
  3. 保存客户端VM状态(类似hibernate)。

我看到这个连接仍然是在Server中建立的

代码语言:javascript
复制
netstat -anp --tcp 

换句话说,在服务器中没有触发EPOLLIN。

single/TCP-Keepalive-HOWTO/说,默认情况下,它将保持大约7200秒。

当然,您可以通过setsockopt或内核参数更改“保持活动超时”值。

但是有些书说,更好的解决方案是在应用层检测它,例如设计协议,确保定期发送一些虚拟消息来检测连接状态。

票数 -1
EN

Stack Overflow用户

发布于 2013-11-17 00:10:08

epoll()基本上是poll(),但当您增加fds数量时,它的扩展性更好。当你用它作为边缘触发的界面时,我不知道它会做什么.但是对于触发级别-是的,如果检测到流结束,则将始终返回EPOLLIN,前提是您正在侦听此事件。

尽管你必须知道TCP并不完美。如果另一方不正常地终止连接(系统链接被关闭),则在写入套接字之前,您的侧可能永远不会检测到这一点。TCP_KEEPALIVE可能会有所帮助,但不会有多大帮助。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19665694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档