TCP四次挥手与TIME_WAIT状态
字数 2107 2025-11-02 17:10:18
TCP四次挥手与TIME_WAIT状态
描述
TCP四次挥手是TCP连接正常终止时使用的过程,涉及客户端和服务器之间交换四个特定的数据包(FIN和ACK)。与建立的“三次握手”相对应,终止连接通常需要四个步骤,因此得名“四次挥手”。在这个过程中,一个关键但常被误解的状态是TIME_WAIT状态。理解四次挥手的步骤和TIME_WAIT状态的作用,对于诊断网络连接问题、编写高性能网络应用程序以及应对相关攻击(如连接耗尽攻击)至关重要。
解题过程
我们将分步解析四次挥手的过程,并深入探讨TIME_WAIT状态。
-
连接终止的发起
- 描述:假设一个TCP连接已经建立,通信的双方我们称为“客户端”和“服务器”。当其中一方(例如,完成数据发送的客户端)决定要关闭连接时,它会启动终止流程。
- 动作:客户端会向其TCP栈发送一个关闭指令(例如,在编程中调用
socket.close())。随后,客户端的TCP协议栈会构造一个TCP数据包,并将包头的FIN标志位设置为1(FIN是“Finish”的缩写,表示发送方没有更多数据要发送了)。同时,这个数据包会包含一个序列号(Sequence Number, 假设为u),这个序列号是之前通信中最后一个数据字节的序列号加1。 - 状态变化:发送完这个
FIN包后,客户端的状态从稳定连接状态(ESTABLISHED)转变为FIN_WAIT_1。这意味着客户端正在等待对方对它的FIN请求进行确认。
-
服务器对FIN的确认
- 描述:服务器端收到客户端发来的
FIN包后,它知道客户端希望关闭连接。 - 动作:服务器必须对此进行确认。它会发送一个确认(ACK)包。这个ACK包的确认号(Acknowledgment Number)被设置为收到的
FIN包的序列号加1,即u+1。这表示服务器已经成功收到了序列号直到u的所有数据(包括这个FIN,它消耗一个序列号)。 - 状态变化:
- 客户端收到这个ACK后,知道服务器已确认其关闭请求。于是客户端的状态从
FIN_WAIT_1转变为FIN_WAIT_2。此时,从客户端到服务器方向的连接已经半关闭,客户端不能再发送数据,但还可以接收来自服务器的数据。 - 服务器的状态从
ESTABLISHED转变为CLOSE_WAIT。这表示服务器已经知晓客户端要关闭,并正在等待服务器自身的应用程序关闭连接。
- 客户端收到这个ACK后,知道服务器已确认其关闭请求。于是客户端的状态从
- 描述:服务器端收到客户端发来的
-
服务器发送FIN包
- 描述:服务器端的应用程序完成数据发送后,也会决定关闭连接。
- 动作:服务器端TCP栈会构造一个自己的
FIN包,其序列号(假设为w)基于服务器之前发送的数据流。这个包被发送给客户端。 - 状态变化:发送完
FIN包后,服务器的状态从CLOSE_WAIT转变为LAST_ACK。这意味着服务器已经发出了自己的终止请求,正在等待最后一个确认。
-
客户端对服务器的FIN进行确认
- 描述:客户端收到服务器发来的
FIN包。 - 动作:客户端必须发送一个确认(ACK)包,其确认号为
w+1。 - 状态变化:
- 服务器收到这个ACK后,就认为连接已经正常关闭。服务器的状态从
LAST_ACK转变为CLOSED(初始状态)。 - 关键点在这里:客户端在发送完最后一个ACK后,不会立即进入
CLOSED状态。相反,它会进入一个名为TIME_WAIT的状态。
- 服务器收到这个ACK后,就认为连接已经正常关闭。服务器的状态从
- 描述:客户端收到服务器发来的
-
深入理解TIME_WAIT状态
- 是什么:
TIME_WAIT也称为2MSL等待状态。MSL是“最大报文段生存时间”(Maximum Segment Lifetime),指一个TCP数据包在网络中被丢弃前能存在的最长时间。TIME_WAIT的持续时间通常是2倍的MSL。在现代操作系统中,这个值通常是30秒、60秒或120秒。 - 为什么需要它(两个核心目的):
- 可靠地终止连接:客户端发送的最后一个ACK包有可能会在网络中丢失。如果服务器没有收到这个ACK,它会认为自己的
FIN包丢失了,从而重新发送FIN包。如果客户端在发送ACK后直接进入CLOSED状态并重用相同的端口建立新连接,那么当之前连接迟到的FIN包到达时,它可能会被误认为是新连接的终止信号,从而错误地关闭新连接。处于TIME_WAIT状态的客户端如果收到重传的FIN包,会重新发送ACK,从而保证连接能安全可靠地彻底关闭。 - 让旧连接的报文在网络中消逝:在2MSL的等待时间内,属于这个刚刚关闭的连接的所有延迟的数据包都会因超时而从网络中消失。这确保了这些旧的、迟到的数据包不会与未来重用相同四元组(源IP、源端口、目的IP、目的端口)的新连接产生混淆。
- 可靠地终止连接:客户端发送的最后一个ACK包有可能会在网络中丢失。如果服务器没有收到这个ACK,它会认为自己的
- 是什么:
总结
TCP四次挥手是一个精心设计的、可靠的连接终止机制。TIME_WAIT状态是其不可或缺的一部分,它虽然会暂时占用系统端口资源(可能导致高并发服务器出现“端口耗尽”问题),但其首要目标是保证TCP协议的可靠性。在设计和优化网络服务时,需要理解并妥善处理TIME_WAIT状态,而不是简单地试图绕过它。