IdTCPServer不会释放突然断开连接的客户端

时间:2015-12-21 20:59:51

标签: delphi delphi-2010 indy10

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

1 个答案:

答案 0 :(得分:3)

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

要考虑到这一点,您应该:

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

  2. 如果您无法更改数据协议,则至少可以在套接字本身上启用TCP级别保持活动。在服务器的OnConnect事件中,您可以调用AContext.Binding.SetKeepAliveValues()方法启用keep-alives。然后操作系统将为您处理保持活动,并在超时结束后使连接无效。

  3. 如上所述,还要确保您的服务器事件处理程序不会吞噬Indy异常(源自EIdException)。这也可能导致服务器无法正确终止线程,如果连接丢失并且Indy引发了关于它的异常,但是您不允许服务器处理它。如果需要捕获异常(用于记录等),请确保重新引发任何EIdException派生的异常并让服务器处理它。