外观
三次握手与四次挥手
⭐ 题目日期:
美团 - 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 实现了 可靠连接建立 和 安全连接释放,是保障网络通信稳定的核心机制。
