外观
三次握手与四次挥手
⭐ 题目日期:
美团 - 2025/04/12,腾讯 - 2024/08/19
📝 题解:
一、三次握手(Three-Way Handshake)
目的:建立 TCP 连接,确保双方通信能力正常,并同步初始序列号(ISN)。 流程:
- SYN(客户端→服务端):
- 客户端发送
SYN=1
标志的报文,并携带随机生成的初始序列号seq=x
。 - 状态变化:客户端进入
SYN_SENT
状态。
- 客户端发送
- SYN-ACK(服务端→客户端):
- 服务端收到
SYN
后,回复SYN=1
和ACK=1
的报文,携带自己的初始序列号seq=y
,并确认客户端的序列号ack=x+1
。 - 状态变化:服务端进入
SYN_RECEIVED
状态。
- 服务端收到
- ACK(客户端→服务端):
- 客户端确认服务端的
SYN
,发送ACK=1
报文,确认号ack=y+1
。 - 状态变化:双方进入
ESTABLISHED
状态,连接建立完成。
- 客户端确认服务端的
为什么需要三次?
- 防止历史连接干扰:若客户端发送的旧
SYN
报文因网络延迟到达,服务端会误认为新连接请求,三次握手确保客户端能识别并拒绝旧连接。 - 同步双方初始序列号:确保双方能正确组装数据包。
二、四次挥手(Four-Way Handshake)
目的:安全关闭 TCP 连接,确保双方数据收发完成。 流程:
- FIN(主动关闭方→被动关闭方):
- 主动方发送
FIN=1
报文,携带序列号seq=u
。 - 状态变化:主动方进入
FIN_WAIT_1
状态。
- 主动方发送
- ACK(被动关闭方→主动关闭方):
- 被动方收到
FIN
后,回复ACK=1
和确认号ack=u+1
。 - 状态变化:被动方进入
CLOSE_WAIT
状态,主动方进入FIN_WAIT_2
状态。
- 被动方收到
- FIN(被动关闭方→主动关闭方):
- 被动方处理完剩余数据后,发送
FIN=1
报文,携带序列号seq=v
。 - 状态变化:被动方进入
LAST_ACK
状态。
- 被动方处理完剩余数据后,发送
- ACK(主动关闭方→被动关闭方):
- 主动方回复
ACK=1
和确认号ack=v+1
。 - 状态变化:主动方进入
TIME_WAIT
状态,等待2MSL
(最长报文段寿命)后关闭;被动方收到后立即关闭。
- 主动方回复
为什么需要四次?
- 全双工通信特性:双方需独立关闭发送通道。
- 确保数据完整性:被动方可能仍有数据待发送,需两次
FIN
和两次ACK
确保双方均完成关闭。
三、关键问题与场景
- TIME_WAIT 状态的作用
- 防止旧连接报文干扰:等待
2MSL
(通常 1-4 分钟)确保网络中残留的报文失效。 - 确保被动方正确关闭:若主动方最后的
ACK
丢失,被动方会重发FIN
,TIME_WAIT
允许主动方重新响应。
- 防止旧连接报文干扰:等待
- SYN 洪泛攻击(SYN Flood)
- 原理:攻击者伪造大量
SYN
报文但不回复ACK
,耗尽服务端资源。 - 防御:使用
SYN Cookie
或限制半连接队列大小。
- 原理:攻击者伪造大量
- 异常情况处理
- 握手阶段丢包:未收到
SYN-ACK
的客户端会重试SYN
(超时重传)。 - 挥手阶段丢包:未收到
FIN
的一方会超时重传或依赖保活机制(Keep-Alive)。
- 握手阶段丢包:未收到
四、总结
通过三次握手和四次挥手,TCP 实现了 可靠连接建立 和 安全连接释放,是保障网络通信稳定的核心机制。