2015-12-21 17 views
0

我通过切断其互联网连接测试了多个客户端的模拟断开连接。我发现TIdTCPServer没有释放它们的线程,但没有检测到它们的断开。相比之下,当我手动关闭客户端时,服务器检测到断开连接并释放其线程。IdTCPServer不会释放突然断开连接的客户

回答

3

操作系统未及时检测到异常断开连接。丢失的套接字连接在内部超时可能需要相当长的时间,因此操作系统可能会使其无效。在操作系统这样做之前,Indy无法知道客户端连接已经消失。

为了说明这一点,你应该:

  1. 实现您的应用层数据协议超时。如果您希望客户端将某些内容发送到您的服务器,并且在一段时间内不这样做,则假定客户端已关闭并关闭连接。在闲置活动期间,要求客户端定期向服务器发送心跳命令,以保持其连接处于活动状态。您可以使用AContext.Connection.IOHandler.CheckForDataOnSource()方法等待数据到达,也可以使用AContext.Binding.SetSockOpt()方法指定阻止读取的SO_RCVTIMEO超时。

  2. 如果你不能改变你的数据协议,你至少可以在套接字本身上启用TCP层保持活动。在服务器的OnConnect事件中,您可以调用AContext.Binding.SetKeepAliveValues()方法启用保活。然后操作系统会为您处理保留状态,并且如果超时超时,连接将失效。

这样说,还要确保你的服务器事件处理程序没有吞咽Indy异常(从EIdException派生)。这也可能导致服务器不能正确终止线程,如果连接丢失并且Indy引发异常,但您不允许服务器处理它。如果您需要捕获异常(用于记录等),请确保重新提出任何EIdException衍生的异常,并让服务器处理它。

相关问题