我已经创建了通过 TCP 套接字进行通信的客户端和服务器程序。
当我有多个客户端时,我可以看到服务器为每个客户端生成进程。但如果我的客户端突然关闭,服务器不会关闭相应的进程。
请帮忙在服务器端检测客户端电源是否关闭,以便退出相关进程。
检查客户端是否处于活动状态应通过编程方式完成,并且 ping 不是一种选择,因为防火墙不允许这样做
亲切的问候
答案1
参见此文档:https://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html
从上述文档中,从好到坏的排序为:
- 在应用协议框架中添加一条保持活动消息(一条空消息)。长度前缀和分隔的系统可能会发送空消息(例如,长度前缀为“0 字节”或单个“结束分隔符”)。
优点。更高级别的协议(实际消息)不受影响。
缺点。这需要更改连接两端的软件,因此如果应用程序协议已指定且不可改变,则这可能不是一个选择。
- 向实际应用程序协议添加一条保持活动消息(“空”消息)。这会向应用程序协议添加一条新消息:“空”消息,应被忽略。
优点。如果应用协议使用非统一的消息框架系统,则可以使用这种方法。在这种情况下,不能使用第一种解决方案。
缺点。(与第一个解决方案相同)这需要更改连接两端的软件,因此如果应用程序协议已指定且不可变,则这可能不是一个选择。
- 显式计时器假设最坏情况。设置一个计时器,并假设计时器到期时连接已断开(当然,每次传输数据时都会重置计时器)。如果 HTTP 服务器支持持久连接,则这就是其工作方式。
优点。不需要更改应用程序协议;在无法更改远程端代码的情况下,前两种解决方案无法使用。此外,此解决方案产生的网络流量较少;它是唯一不涉及发送 keepalive(即“你还在吗?”)数据包的解决方案。
缺点。根据协议的不同,这可能会导致大量有效连接被丢弃。
- 操纵 TCP/IP 保持活动数据包设置。这是一个极具争议的解决方案,其优缺点都有复杂的论据。Stevens 的书第 23 章对此进行了深入讨论。本质上,这会指示 TCP/IP 堆栈代表应用程序定期发送保持活动数据包。
优点。一旦设置 keepalive 参数的代码正常工作,应用程序就无需进行其他任何更改。其他解决方案都有应用程序必须响应的计时器事件;这个是“设置并忘记”。
缺点。RFC 1122 第 4.2.3.6 节指出,路由器可能无法可靠地传输不含数据的 TCP 保持连接的确认;这可能会导致有效连接被丢弃。此外,TCP/IP 堆栈根本不需要支持保持连接(许多嵌入式堆栈不支持),因此该解决方案可能无法转换到其他平台。