libevent2 http 未检测到客户端网络中断
Posted
技术标签:
【中文标题】libevent2 http 未检测到客户端网络中断【英文标题】:libevent2 http not detecting client network broken 【发布时间】:2015-04-03 04:19:52 【问题描述】:这里就不贴源代码了,如果有人重现问题,请到this github project下载代码:
它是一个 Comet 服务器,服务器使用 libevent-2.0.21-stable http。
重现问题:
-
从机器 S 启动 icomet-server
从另一台机器 C 运行
curl http://ip:8100/stream
,服务器 S 将显示 C 已连接的消息
如果我按 CTRL + C 来终止 curl,服务器知道 C 已按预期断开。
如果我从机器 C 中拔出网络线(物理网络断开),服务器将不知道 C 已断开连接,它应该知道!
请问熟悉libevent的朋友,如何让libevent 2检测客户端网络中断?
【问题讨论】:
【参考方案1】:当物理网络链接中断时,您不会总是收到一个数据包来告诉您连接丢失。如果您想了解断开连接,请定期发送 ping(仅要求无操作回复的请求),如果回复没有在合理的超时时间内出现,则假设出现问题。或者,如果客户端空闲时间足够长,则直接断开连接。
当你按 Ctrl-C 时,另一端正在运行的操作系统仍在工作,因此它能够生成一个 TCP RST 数据包来通知你的服务器客户端已经离开。但是,当您断开该物理链接时,客户端将不再能够发出求救的呼声。必须有别的东西来推断客户离开了。
现在,如果您尝试向客户端发送一些数据,服务器内核会(迟早)注意到客户端没有回复其消息。此时,您会看到断开连接 - 但这可能需要几分钟才能发生。如果您没有发送任何数据,那么它将保持打开状态,直到您断开它,或者内核尝试 TCP keepalive(内核的一种低级方式询问“嘿,我没有有一段时间没有收到你的消息,你还在吗?”)可能会在几个小时后(或者它甚至可能根本不为你做保活,这取决于事情的配置方式)。
【讨论】:
谢谢!您提到如果服务器向客户端发送一些数据,它将发现客户端的断开连接 - “但这可能需要几分钟才能发生”。这是一种可接受的方法,我能够实施,但另一个问题 - 如何缩短时间(例如 3 秒)?有没有关于这个的 libevent 配置? 这是由 TCP 重新传输超时控制的,如果不使网络严重不可靠,您不能真正缩短它太多。使用这样的配置,需要在这 3 秒内发生多次重新传输,这可能会在网络上产生大量负载,因为网络过载而丢弃数据包。此外,几秒钟的网络中断非常常见(尤其是对于移动设备),因此您可能不希望如此快速地响应。以上是关于libevent2 http 未检测到客户端网络中断的主要内容,如果未能解决你的问题,请参考以下文章