00.02.TCP协议的三次握手与四次挥手详解
前言
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接、可靠的传输层协议,其核心机制之一是通过“三次握手”建立连接,通过“四次挥手”终止连接,以确保数据传输的可靠性和完整性。
一、TCP三次握手:建立连接的过程
三次握手(Three-Way Handshake)是TCP建立连接时的核心流程,目的是让通信双方确认彼此的发送和接收能力,并协商初始序列号(ISN,Initial Sequence Number),为后续数据传输奠定基础。
核心背景
- TCP连接是双向的,双方都需要确认“自己能发、对方能收”以及“对方能发、自己能收”。
- 序列号(Sequence Number)是TCP可靠性的关键,用于标识数据字节的顺序,避免重复或乱序。
三次握手具体步骤
1. 第一次握手(客户端 → 服务器:SYN=1,ISN=x)
-
发起方:客户端(主动打开连接的一方)向服务器发送一个SYN报文段(同步报文段)。
-
报文关键字段:
SYN标志位设为1(表示请求建立连接)。- 初始序列号
Sequence Number = x(客户端随机生成的初始序列号,用于标识后续发送数据的起始位置)。 - 不携带应用数据。
-
状态变化:客户端从
CLOSED状态进入SYN-SENT状态,等待服务器响应。
2. 第二次握手(服务器 → 客户端:SYN=1,ACK=1,ISN=y,确认号=x+1)
-
响应方:服务器收到客户端的SYN报文后,若同意建立连接,则返回一个SYN+ACK报文段。
-
报文关键字段:
SYN标志位设为1(表示服务器也请求建立连接)。ACK标志位设为1(表示确认收到客户端的报文)。- 服务器的初始序列号
Sequence Number = y(服务器随机生成的初始序列号)。 - 确认号
Acknowledgment Number = x + 1(表示已收到客户端的SYN报文,下一次期望接收客户端从x + 1开始的数据)。
-
状态变化:服务器从
LISTEN状态进入SYN-RCVD状态,等待客户端确认。
3. 第三次握手(客户端 → 服务器:ACK=1,确认号=y+1)
-
确认方:客户端收到服务器的SYN+ACK报文后,确认连接建立的条件已满足,向服务器发送一个ACK报文段。
-
报文关键字段:
ACK标志位设为1(表示确认收到服务器的SYN报文)。- 序列号
Sequence Number = x + 1(基于客户端初始序列号递增,因第一次握手已消耗一个序列号)。 - 确认号
Acknowledgment Number = y + 1(表示已收到服务器的SYN报文,下一次期望接收服务器从y + 1开始的数据)。
-
状态变化:
- 客户端发送ACK后,从
SYN-SENT状态进入ESTABLISHED状态(连接已建立,可开始发送数据)。 - 服务器收到ACK后,从
SYN-RCVD状态进入ESTABLISHED状态。
- 客户端发送ACK后,从
三次握手的必要性
- 为何不是两次? 两次握手无法确保双方都确认“对方已准备好接收数据”。例如,若客户端的SYN报文因网络延迟滞留,客户端超时后重发SYN并建立连接,而滞留的SYN后续到达服务器,服务器会误以为是新连接请求并回复SYN+ACK,此时客户端已进入连接状态,不会响应,导致服务器资源浪费。三次握手通过第三次确认,可避免此类无效连接。
- 为何不是四次? 第二次握手将服务器的SYN和对客户端的ACK合并发送,减少了一次通信,提高效率,因此无需四次。
二、TCP四次挥手:终止连接的过程
四次挥手(Four-Way Wavehand)是TCP终止连接时的流程,由于TCP连接是双向的,双方需分别关闭各自的发送通道,因此需要四次交互。
核心背景
- TCP连接的关闭是单向进行的:一方先关闭发送数据的通道(“半关闭”),另一方继续发送数据,直到也关闭通道。
- 终止连接时需确保双方已完成所有数据传输,且所有数据都被确认。
四次挥手具体步骤
1. 第一次挥手(主动关闭方 → 被动关闭方:FIN=1,序列号=u)
-
发起方:假设客户端决定关闭连接(主动关闭方),向服务器发送一个FIN报文段(结束报文段)。
-
报文关键字段:
FIN标志位设为1(表示客户端不再发送数据,但仍可接收数据)。- 序列号
Sequence Number = u(客户端当前的序列号,等于已发送数据的最后一个字节序号 + 1)。
-
状态变化:客户端从
ESTABLISHED状态进入FIN-WAIT-1状态,等待服务器确认。
2. 第二次挥手(被动关闭方 → 主动关闭方:ACK=1,确认号=u+1)
-
响应方:服务器收到客户端的FIN报文后,返回一个ACK报文段,确认已收到关闭请求。
-
报文关键字段:
ACK标志位设为1。- 确认号
Acknowledgment Number = u + 1(表示已收到客户端的FIN,下一次期望接收u + 1开始的数据,但客户端已无数据发送)。 - 序列号
Sequence Number = v(服务器当前的序列号,基于已发送数据的序号)。
-
状态变化:
- 服务器进入
CLOSE-WAIT状态(此时TCP连接进入“半关闭”状态,服务器仍可向客户端发送数据,客户端需接收)。 - 客户端收到ACK后,从
FIN-WAIT-1进入FIN-WAIT-2状态,等待服务器的FIN报文。
- 服务器进入
3. 第三次挥手(被动关闭方 → 主动关闭方:FIN=1,ACK=1,序列号=w,确认号=u+1)
-
发起方:服务器完成所有数据发送后,向客户端发送FIN+ACK报文段,表示自己也不再发送数据。
-
报文关键字段:
FIN标志位设为1,ACK标志位设为1。- 序列号
Sequence Number = w(服务器发送完所有数据后的序列号)。 - 确认号
Acknowledgment Number = u + 1(再次确认收到客户端的FIN)。
-
状态变化:服务器从
CLOSE-WAIT状态进入LAST-ACK状态,等待客户端的最终确认。
4. 第四次挥手(主动关闭方 → 被动关闭方:ACK=1,确认号=w+1)
-
确认方:客户端收到服务器的FIN+ACK报文后,发送最后一个ACK报文段,确认关闭服务器的发送通道。
-
报文关键字段:
ACK标志位设为1。- 序列号
Sequence Number = u + 1(客户端基于第一次挥手的序列号递增)。 - 确认号
Acknowledgment Number = w + 1(表示已收到服务器的FIN,下一次期望接收w + 1开始的数据)。
-
状态变化:
- 客户端发送ACK后,进入
TIME-WAIT状态(等待一段时间,确保服务器收到ACK,避免因ACK丢失导致服务器重发FIN)。 - 服务器收到ACK后,从
LAST-ACK状态进入CLOSED状态(连接完全关闭)。 - 客户端在
TIME-WAIT状态等待 2MSL(Maximum Segment Lifetime,报文最大生存时间) 后,进入CLOSED状态。
- 客户端发送ACK后,进入
四次挥手的关键细节
- TIME-WAIT状态的作用:防止最后一个ACK报文丢失,若服务器未收到ACK会重发FIN,客户端在TIME-WAIT期间可再次发送ACK;同时确保网络中残留的旧报文段已过期,避免新连接受到干扰。
- 为何需要四次挥手? 第二次挥手仅确认客户端的关闭请求,此时服务器可能仍有数据发送,无法立即发送FIN;第三次挥手才是服务器完成数据发送后的关闭请求,因此需分两次交互,加上客户端的两次发送,共四次。
三、总结
| 过程 | 核心目的 | 关键标志位 | 状态变化核心节点 |
|---|---|---|---|
| 三次握手 | 建立双向连接,协商初始序列号 | SYN=1,ACK=1 | 客户端:SYN-SENT → ESTABLISHED 服务器:SYN-RCVD → ESTABLISHED |
| 四次挥手 | 终止双向连接,确保数据传输完成 | FIN=1,ACK=1 | 主动方:FIN-WAIT-1 → TIME-WAIT → CLOSED 被动方:CLOSE-WAIT → LAST-ACK → CLOSED |
TCP的三次握手和四次挥手是其可靠性的基础,通过严格的状态管理和确认机制,确保了连接建立和终止的有序性,为应用层数据传输提供了稳定的底层保障。
本文来自博客园,作者:{雾里看浮光(南知意)},转载请注明原文链接:{https://www.cnblogs.com/JaseLee}

浙公网安备 33010602011771号