TCP 的三次握手和四次挥手
你对 TCP 核心特性和通讯阶段的概括非常精准,这正是理解 TCP 如何保障数据可靠传输的关键。下面将从核心特性解析、三阶段通讯流程、关键保障机制三个维度展开分析,帮你更深入理解其设计逻辑。
一、核心特性解析:可靠与面向连接的本质
TCP 的 "可靠" 和 "面向连接" 并非孤立概念,而是相互支撑的设计目标,具体体现在两个层面:
-
面向连接:通讯前必须通过 "三次握手" 建立逻辑连接,确保双方都具备收发数据的能力;通讯结束后通过 "四次挥手" 释放连接,避免资源浪费。这区别于 UDP 的 "无连接" 模式(无需建立连接即可直接发数据)。
-
可靠性保障:通过多种机制确保数据 "不丢、不重、不乱序",比如确认应答(ACK)、超时重传、序号机制等,这些机制依赖 "面向连接" 建立的双向通信通道才能生效。
二、通讯三阶段:流程与设计逻辑
TCP 的通讯过程严格遵循 "建立连接→数据传输→释放连接" 的顺序,每个阶段的步骤都对应明确的功能目标。
1. 建立连接:三次握手(Three-Way Handshake)
核心目标是确认双方的收发能力正常,并协商初始序号(ISN),避免历史无效数据干扰。流程如下:
-
第一次握手(客户端→服务器) :客户端发送
SYN报文(同步报文段),携带自己的初始序号ISN_client,请求建立连接。此时客户端进入SYN_SENT状态。 -
第二次握手(服务器→客户端) :服务器收到
SYN后,回复SYN+ACK报文,携带自己的初始序号ISN_server,并确认客户端的序号(ACK=ISN_client+1)。此时服务器进入SYN_RCVD状态。 -
第三次握手(客户端→服务器) :客户端收到
SYN+ACK后,发送ACK报文,确认服务器的序号(ACK=ISN_server+1)。此时双方均进入ESTABLISHED状态,连接正式建立。
为什么需要三次?
若只两次握手,服务器无法确认客户端是否能收到自己的
SYN+ACK(比如该报文丢失),会导致服务器一直占用资源等待;三次握手能让双方都验证 "对方能收也能发",避免资源浪费。
2. 数据传输:可靠传输的核心环节
连接建立后进入数据传输阶段,TCP 通过以下机制保障可靠性:
-
序号与确认机制:每个数据段都带 "序号"(Seq),接收方收到后回复 "确认号"(ACK=Seq+1),告知发送方 "已收到该序号及之前的所有数据"。
-
超时重传:发送方若在规定时间内未收到确认,会重传该数据段(超时时间会动态调整,避免网络拥堵)。
-
流量控制:通过 "滑动窗口" 机制,接收方告知发送方 "自己当前能接收的最大数据量",避免发送方发得太快导致接收方缓存溢出。
-
拥塞控制:当网络出现拥堵(如重传频繁),发送方会减少发送速率,避免加剧网络负担(常见算法有慢启动、拥塞避免)。
3. 释放连接:四次挥手(Four-Way Wavehand)
核心目标是确保双方都已发送完所有数据,再释放连接(因 TCP 是双向通信,需分别关闭两个方向的通道)。流程如下:
-
第一次挥手(客户端→服务器) :客户端发送
FIN报文(结束报文段),表示 "我已无数据要发送,请求关闭我的发送通道",客户端进入FIN_WAIT_1状态。 -
第二次挥手(服务器→客户端) :服务器收到
FIN后,回复ACK报文,确认 "已收到你的关闭请求",服务器进入CLOSE_WAIT状态(此时服务器仍可向客户端发数据)。客户端收到ACK后,进入FIN_WAIT_2状态。 -
第三次挥手(服务器→客户端) :服务器发送完所有剩余数据后,发送
FIN报文,表示 "我也无数据要发送,请求关闭我的发送通道",服务器进入LAST_ACK状态。 -
第四次挥手(客户端→服务器) :客户端收到
FIN后,回复ACK报文,确认 "已收到你的关闭请求",客户端进入TIME_WAIT状态(等待 2MSL 时间,确保服务器收到确认,避免重传);服务器收到ACK后,直接关闭连接。
为什么需要四次?
第二次挥手只是 "确认客户端的关闭请求",服务器可能还在发数据,不能直接发
FIN;需等服务器发完数据后,再发第三次挥手的FIN,因此比三次握手多一次交互。
三、关键总结:TCP 设计的核心逻辑
TCP 的所有机制都围绕 "在不可靠的 IP 网络上,提供可靠的双向字节流传输" 展开:
-
"面向连接" 是基础:通过三次握手建立信任通道,为后续可靠传输铺路;
-
"可靠性" 是核心:通过序号、确认、重传、流控、拥塞控制等机制,解决 "丢包、重传、乱序、拥堵" 等问题;
-
"四次挥手" 是收尾:确保双方数据都已传输完成,避免数据残留或资源泄漏。
一、TCP 三次握手(建立连接)流程图
核心目的:确认客户端与服务器的收发能力正常,协商初始序号(ISN),建立可靠通信通道。
| 步骤 | 发起方 | 接收方 | 发送报文 | 发起方状态变化 | 接收方状态变化 | 核心目的 |
|---|---|---|---|---|---|---|
| 1 | 客户端 | 服务器 | SYN (Seq=ISNc) | CLOSED → SYN_SENT | LISTEN → SYN_RCVD | 客户端请求建立连接,告知服务器自己的初始序号(ISNc) |
| 2 | 服务器 | 客户端 | SYN+ACK (Seq=ISNs, ACK=ISNc+1) | 无(维持 SYN_RCVD) | SYN_SENT → ESTABLISHED | 服务器响应连接请求:告知自己的初始序号(ISNs),并确认已收到客户端的 SYN |
| 3 | 客户端 | 服务器 | ACK (Seq=ISNc+1, ACK=ISNs+1) | 无(维持 ESTABLISHED) | SYN_RCVD → ESTABLISHED | 客户端确认已收到服务器的 SYN,双方均进入 "已连接" 状态,连接正式建立 |
二、TCP 四次挥手(释放连接)流程图
核心目的:确保双方所有数据已传输完成,分别关闭双向通信通道,避免资源泄漏。
| 步骤 | 发起方 | 接收方 | 发送报文 | 发起方状态变化 | 接收方状态变化 | 核心目的 |
|---|---|---|---|---|---|---|
| 1 | 客户端 | 服务器 | FIN (Seq=K) | ESTABLISHED → FIN_WAIT_1 | 无(维持 ESTABLISHED) | 客户端告知服务器:"我已无数据要发,请求关闭我的发送通道" |
| 2 | 服务器 | 客户端 | ACK (ACK=K+1) | 无(维持 FIN_WAIT_1) | ESTABLISHED → CLOSE_WAIT | 服务器确认收到关闭请求,此时服务器仍可向客户端发送剩余数据 |
| 3 | 服务器 | 客户端 | FIN (Seq=L) | FIN_WAIT_1 → FIN_WAIT_2 | CLOSE_WAIT → LAST_ACK | 服务器发送完所有数据,告知客户端:"我也无数据要发,请求关闭我的发送通道" |
| 4 | 客户端 | 服务器 | ACK (ACK=L+1) | FIN_WAIT_2 → TIME_WAIT | LAST_ACK → CLOSED | 客户端确认收到服务器的关闭请求,服务器直接关闭;客户端等待 2MSL 后关闭,确保服务器收到确认 |
关键补充说明
-
状态含义:
-
LISTEN:服务器处于 "监听" 状态,等待客户端连接请求。 -
ESTABLISHED:双方已建立连接,可正常传输数据。 -
TIME_WAIT:客户端等待 2MSL(报文最大生存时间),避免服务器因未收到 ACK 而重传 FIN,导致连接残留。
-
-
序号(Seq)与确认号(ACK):
- 每次发送数据后,Seq 会累加数据长度;ACK 始终是 "期望收到的下一个 Seq",表示 "该序号之前的数据已全部收到"。
-
双向关闭:TCP 是双向通信,四次挥手本质是 "客户端关闭发送通道→服务器确认→服务器关闭发送通道→客户端确认",因此比三次握手多 1 次交互。