2015-04-03 45 views
0

这里我不粘贴的源代码,如果任何一个什么重现该问题,从this github project下载代码:libevent2 HTTP未检测客户端网络打破

这是一个彗星服务器,该服务器使用的libevent-2.0 .21稳定的http。

要重现该问题:

  1. 启动从机S的icomet服务器
  2. 从另一机器C运行curl http://ip:8100/stream,服务器S将表明,C已连接
  3. 消息,如果我按CTRL + C要终止curl,服务器知道C按预期断开连接。
  4. 如果我从机器C(物理网络断开)拔出网络线路,服务器将不知道C断开连接,它应该知道!

我会问一个熟悉libevent的人,如何让libevent 2检测到客户端网络坏了?

回答

1

当物理网络连接中断时,您不会总是收到一个数据包,告诉您丢失了连接。如果您想查找断开连接的信息,请定期发送一个ping(请求只是要求无操作应答),并且如果回复没有达到合理的超时时间,则认为出现了问题。或者只要断开客户端,如果他们闲置足够长的时间。

当你这样做了Ctrl-C时,另一端运行的操作系统仍在工作,所以它能够生成一个TCP RST包来通知你的服务器客户端已经消失。但是,当你打破这种物理链接时,客户不再能够发出求救的声音。还有一些事情必须推断客户走开了。

现在,如果您尝试向客户端发送一些数据,服务器内核将会注意到(迟早)客户端没有回复其消息。此时您会看到断开连接 - 但这可能需要几分钟才能发生。如果你是而不是发送任何数据,那么它会一直保持打开状态,直到你断开连接,或者内核尝试TCP keepalive(内核的一个低级别的方式询问“嗨,我没有收到你的消息一段时间后,你还在吗?“)可能几小时后(或者甚至可能根本不会为你做保存活动,这取决于配置的方式)。

+0

谢谢!您提到服务器是否向客户端发送了一些数据,它会发现客户端的断开连接 - “但这可能需要几分钟才能发生”。这是一个可接受的方法,我能够实现,但另一个问题 - 如何缩短时间(例如3秒)?有没有关于这个的libevent配置? – ideawu 2015-04-03 07:48:02

+0

这是由TCP重新传输超时管理的,你不能真正缩短它,而不会使网络严重不可靠。使用这样的配置,多次重传将需要在3秒内发生,这可能会在丢包的网络上创建大量负载,因为它的负载过重。此外,几秒钟的网络丢失非常普遍(特别是对于移动设备),所以您可能不想反应如此迅速。 – bdonlan 2015-04-03 07:54:27