一旦连接建立,如果没有对等方发送任何数据,则网络上不会发送任何数据包。TCP 是一个空闲协议,因此它假设连接处于活动状态。
断开连接的原因- 应用程序关闭:当进程结束时,通常会发送 FIN 数据包,通知对方连接已关闭。但如果进程崩溃,则无法保证该数据包会被发送给对方。
- 设备关闭:如果设备关闭,很可能不会有任何通知。
- 网线拔出:如果网线被拔出,相当于路由器关闭,没有数据传输,因此连接不会关闭。
- 路由器信号丢失:如果应用程序丢失路由器信号,连接仍将保持活动状态。
检测半开连接断开
您可以尝试使用以下方法检测断开连接
第二个连接
您可以尝试打开第二个连接并尝试连接,但这有一些缺点,例如消耗更多资源、创建新线程……如果对等方已重启,第二个连接将正常工作,但第一个不会。
Ping 对等方如果您尝试通过半开连接发送 ping 或任何消息,您会发现不会收到任何错误。
在 TCP 套接字级别启用 KeepAliveTCP keep-alive 数据包只是一个 ACK,其序列号比当前连接的序列号少一个。接收到这些 ACK 的主机会响应一个当前序列号的 ACK。Keep-alive 可用于验证连接远端的计算机是否仍然可用。如果 TCP 连接上没有其他数据或更高级别的 keep-alive 传输,TCP keep-alive 可以每隔 TCPKeepAlive.Time(默认为 7,200,000 毫秒或两小时)发送一次。如果没有收到 keep-alive 响应,则每隔 TCPKeepAlive.Interval 秒重复一次。KeepAliveInterval 默认为 1000 毫秒。
您可以启用每个连接的 KeepAlive,让 TCP 协议检查连接是否处于活动状态。如果您想检测断开的连接(例如:拔出网线时),这是首选方法。从 sgcWebSockets 4.3.7 开始,您可以启用 TCPKeepAlive 属性来尝试检测这些半开连接。
oClient := TsgcWebSocketClient.Create(nil); oClient.TCPKeepAlive.Enabled := True; oClient.TCPKeepAlive.Time := 3000; oClient.TCPKeepAlive.Interval := 1000;
