每日一题
TCP三次握手详解
三次握手(Three-Way Handshake) 是TCP协议建立可靠连接的核心过程,确保通信双方能够正常收发数据并同步初始序列号。以下是详细步骤和原理:
1. 第一次握手:SYN(客户端 → 服务器)
- 动作:客户端发送一个TCP报文,设置
SYN=1
(同步标志位),并生成一个随机初始序列号(ISN)seq=x
。 - 目的:
- 通知服务器客户端希望建立连接。
- 告知服务器客户端数据的起始序列号为
x
(用于后续数据顺序控制)。
- 客户端状态:
SYN_SENT
(等待服务器确认)。
2. 第二次握手:SYN-ACK(服务器 → 客户端)
- 动作:服务器收到SYN报文后,回复一个报文,设置
SYN=1
和ACK=1
(确认标志位),并生成自己的随机初始序列号seq=y
,同时确认号为ack=x+1
。 - 目的:
- 确认客户端的SYN(
ACK=1
和ack=x+1
表示已收到客户端的序列号x
,期望下次收到x+1
)。 - 告知客户端服务器的初始序列号为
y
。
- 确认客户端的SYN(
- 服务器状态:
SYN_RECEIVED
(等待客户端最终确认)。
3. 第三次握手:ACK(客户端 → 服务器)
- 动作:客户端收到SYN-ACK后,发送一个确认报文,设置
ACK=1
,序列号为seq=x+1
,确认号为ack=y+1
。 - 目的:
- 确认服务器的SYN(
ACK=1
和ack=y+1
表示已收到服务器的序列号y
,期望下次收到y+1
)。 - 完成连接的建立。
- 确认服务器的SYN(
- 双方状态:进入
ESTABLISHED
(连接已建立),可以开始传输数据。
为什么需要三次握手?
- 防止历史连接干扰:
- 若客户端发送了多个重复的SYN(如网络延迟导致旧的SYN到达服务器),三次握手确保服务器能通过客户端的最终ACK确认最新连接,丢弃旧的SYN。
- 同步双方初始序列号:
- 客户端和服务器通过三次握手交换初始序列号(
x
和y
),确保后续数据传输的连续性。
- 客户端和服务器通过三次握手交换初始序列号(
- 验证双向通信能力:
- 三次握手确认客户端和服务器的发送能力和接收能力均正常(客户端能发SYN并收ACK,服务器能收SYN并发ACK,客户端最终确认)。
- 避免资源浪费:
- 如果是两次握手,服务器在收到SYN后直接建立连接,若客户端未收到响应,服务器会一直等待,导致资源浪费。三次握手确保双方都确认后才正式连接。
常见问题
Q1:第三次握手(ACK)丢失会怎样?
- 服务器未收到ACK会重传SYN-ACK报文(超时重试)。
- 客户端已处于
ESTABLISHED
状态,若直接发送数据,数据包中的ACK字段(ack=y+1
)会被服务器识别,触发服务器进入ESTABLISHED
状态。
Q2:为什么初始序列号是随机的?
- 防止攻击者伪造相同序列号的数据包(安全考虑)。
- 避免不同连接的报文混淆(如旧连接的报文干扰新连接)。
总结
三次握手是TCP可靠性的基石,通过两次SYN同步序列号和一次ACK最终确认,解决了以下问题:
- 确保双方通信能力正常。
- 避免历史连接导致的数据混乱。
- 为后续数据传输提供有序的序列号基础。
理解三次握手是掌握TCP协议的关键,也是排查网络连接问题(如连接超时、丢包)的核心知识。