半开连接(half-open connection)

本文解析了TCP半开连接的概念,探讨其产生的原因,包括进程崩溃、电脑崩溃和路由器重启。重点介绍了如何在不同场景下检测连接丢失,以及保持连接正常的方法,如添加keepalive消息和使用显式计时器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

半开(half-open)连接

开始一个TCP连接需要三次握手协议,关闭TCP连接需要四次挥手协议。一旦连接已经建立,即使双方没有发送任何数据,TCP也会假设连接是存活的,除非能证明连接已经关闭。

TCP以这种设计方式来提高弹性和效率。这种设计可以从网络和路由器崩溃中正常恢复。例如,客户端连接到服务器,中间路由器可能会重新启动,并且在路由器恢复后,原始连接仍然存在(除非在路由器关闭时通过连接发送数据,否则为真)。这种设计很有效,因为没有通过网络发送“轮询”数据包来检查连接是否正常(减少不必要的网络流量)。

TCP确实有对数据的确认,当一端向另一端发送数据时,如果连接仍然处于活动状态,它将收到确认消息,因此,可以通过发送数据来检测连接是否断开。需要注意的是,接收数据在TCP中是完全被动的;仅读取套接字并不能检测出连接是否断开

这导致了一种被称为 “半连接”状态。在TCP协议中,一端发送消息,另一端接收消息。如果中间路由器突然重启,接收方将继续等待消息到达,发送方将发送数据,并收到一个指示连接丢失的错误。由于连接断开只能通过发送数据来检测,因此接收方将永远等待。这种情况被称为“半连接”状态,一端意识到连接丢失,另一端认为连接仍处于活动状态

半开连接的原因

  • 进程崩溃:如果一个进程正常关闭,它通常会发送一个FIN,通知对方连接已经关闭。然而,如果进程崩溃或终止,则无法保证是否会发送FIN。操作系统可能会代表崩溃的进程发出FIN数据包,但是,这取决于操作系统。
  • 电脑崩溃:如果整个计算机崩溃或断电,那么肯定不会通知对方连接已丢失。
  • 路由器崩溃或重启:从一端到另一端的路由上的任何路由器都有可能崩溃或重新启动。如果当时正在发送数据,这会导致连接丢失。如果在那个确切时间没有发送数据,则连接不会丢失。

是否需要显式检测

在某些情况下,不需要检测。一个轮询系统拥有一个内置的定时器,并定时通过连接发送数据。所以轮询端不需要显式检查连接是否丢失。

对于通信的每一方,必须分别考虑检测的必要性。例如,如果协议基于轮询方案,那么进行轮询的一方不需要明确的keepalive处理,响应轮询操作的一端需要keepalive处理。

检测断开连接的错误方法

  • Ping:向远程端发送ping(ICMP)不能判断连接是否断开。即使连接连接已经断开,Ping操作也可能成功。
  • 建立第二个套接字连接:新的套接字连接不能在所有情况下保证现有连接的有效性。如果远程端崩溃并重新启动,即使原始连接处于半开状态,第二次连接尝试也会成功。

检测断开连接的正确方法

  1. 向应用程序协议框架添加一条keepalive消息(一条空消息)。长度前缀或定界系统可能发送空消息(例如,0字节的长度前缀或单个结束分隔符)。
    1. 优点:更高级别的协议(实际消息)不受影响
    2. 缺点:需要对连接双方的软件进行更改,因此如果应用程序协议已经指定不可改变,则这个方法不可用。
  2. 向实际应用程序协议添加一条keepalive消息(一个NULL消息)。NULL消息应该被忽略。
    1. 优点:如果应用程序协议使用非统一消息帧系统,则可以使用该方法。
    2. 缺点:需要对连接双方的软件进行更改,因此如果应用程序协议已经指定不可改变,则这个方法不可用。
  3. 最坏情况的显式定时器:有一个定时器,假设定时器到期时连接已经断开(每次传输数据时都会重置计时器)。
    1. 优点:不需要更改应用程序协议;在远程端代码无法更改的情况下,前两种解决方案不能使用。此外,该解决方案发送较少的网络流量。这是唯一不涉及发送keepalive数据报的解决方案。
    2. 缺点:可能会导致大量的有效连接被丢弃。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值