我知道,如果远程主机优雅地关闭连接,epoll将报告EPOLLIN,调用read或recv不会阻塞,并返回0字节(即流结束)。
但是,如果连接没有很好地关闭,并且write或send操作失败,这是否会导致epoll随后为该套接字返回EPOLLIN,从而产生相同/类似的流场景?
我试图找到关于这种行为的文档,但是没有成功,虽然我可以对它进行测试,但我不感兴趣的是在特定的发行版上使用特定的内核版本会发生什么。
发布于 2013-11-17 00:43:47
从规范中确实不是很明显,但它适用于poll()
POLLIN。POLLHUP或POLLERR。shutdown(SHUT_WR)),则返回POLLIN,而不返回POLLHUP和POLLERR。(这允许正常地等待POLLOUT。)只要设置了POLLIN、POLLHUP和POLLERR,就可以尝试读取。
在kqueue()中,可能会触发一个EVFILT_READ过滤器。这将在手册页中描述,并且应该足够清楚。
请注意,如果您不启用TCP驻留(默认情况下,FreeBSD启用它们,但大多数其他操作系统不启用),如果网络以某些方式中断,等待读取数据可能会永远停滞不前。即使TCP保持生命是打开的,它往往需要几个小时才能检测到一个断开的连接。
发布于 2013-10-29 18:15:07
当对等机意外关闭时,它可能不会返回EPOLLIN。在过去,我通过VirtualBox将这种现象描述为以下步骤:
我看到这个连接仍然是在Server中建立的
netstat -anp --tcp 换句话说,在服务器中没有触发EPOLLIN。
single/TCP-Keepalive-HOWTO/说,默认情况下,它将保持大约7200秒。
当然,您可以通过setsockopt或内核参数更改“保持活动超时”值。
但是有些书说,更好的解决方案是在应用层检测它,例如设计协议,确保定期发送一些虚拟消息来检测连接状态。
发布于 2013-11-17 00:10:08
epoll()基本上是poll(),但当您增加fds数量时,它的扩展性更好。当你用它作为边缘触发的界面时,我不知道它会做什么.但是对于触发级别-是的,如果检测到流结束,则将始终返回EPOLLIN,前提是您正在侦听此事件。
尽管你必须知道TCP并不完美。如果另一方不正常地终止连接(系统链接被关闭),则在写入套接字之前,您的侧可能永远不会检测到这一点。TCP_KEEPALIVE可能会有所帮助,但不会有多大帮助。
https://stackoverflow.com/questions/19665694
复制相似问题