TCP 三次握手是建立可靠的 TCP 连接的过程,确保客户端和服务器双方都准备好进行通信。三次握手的目的是为了同步双方的序列号和确认号,并协商连接参数。三次握手包括以下步骤:
1. 第一次握手:SYN
-
客户端发送 SYN (Synchronize) 报文: 客户端向服务器发送一个带有 SYN 标志的 TCP 数据包,表示它想要建立连接。这个数据包包含一个随机生成的 初始序列号(Sequence Number, SEQ),用于标识客户端向服务器发送的数据包的顺序。
- 报文段内容:
- SYN = 1
- SEQ = x(客户端的初始序列号)
此时,客户端进入 SYN-SENT 状态,等待服务器的回应。
- 报文段内容:
2. 第二次握手:SYN-ACK
- 服务器发送 SYN-ACK 报文: 收到客户端的 SYN 请求后,服务器确认收到请求,并向客户端发送一个 SYN-ACK 报文,表示愿意建立连接。这个报文包含两个重要信息:
-
ACK(Acknowledgement):用于确认收到客户端的 SYN 报文。服务器的 ACK 序号为 x+1,即客户端的 SEQ 加 1,表示已经收到客户端的 SYN 请求。
-
SYN:服务器向客户端发送自己的 SYN 请求,服务器也会生成一个自己的 初始序列号(SEQ = y)。
-
报文段内容:
- SYN = 1
- ACK = x + 1(确认收到客户端的 SYN)
- SEQ = y(服务器的初始序列号)
-
3. 第三次握手:ACK
-
客户端发送 ACK 报文: 当客户端收到服务器的 SYN-ACK 报文后,客户端需要向服务器发送一个 ACK 报文,以确认连接建立。这个 ACK 报文包含:
-
ACK:确认服务器的 SYN 报文,ACK 序号为 y+1,即服务器的 SEQ 加 1,表示已经收到服务器的 SYN。
-
此时,客户端的序列号 SEQ = x+1。
-
报文段内容:
- ACK = y + 1(确认收到服务器的 SYN)
- SEQ = x + 1
发送完 ACK 报文后,客户端进入 ESTABLISHED 状态,表示连接已建立。
-
-
服务器收到 ACK 报文后,也进入 ESTABLISHED 状态,表示双方可以开始数据传输。
整个三次握手的过程:
markdown
复制代码
1. 客户端 -> 服务器:SYN (SEQ = x) 2. 服务器 -> 客户端:SYN-ACK (SEQ = y, ACK = x + 1) 3. 客户端 -> 服务器:ACK (SEQ = x + 1, ACK = y + 1)
三次握手的目的
-
确保双方的发送和接收能力正常:
- 客户端发出 SYN,服务器收到后发出 SYN-ACK,证明服务器的接收能力正常。
- 客户端收到 SYN-ACK 后发出 ACK,证明客户端的接收和发送能力都正常。
-
同步初始序列号:
- 在三次握手过程中,客户端和服务器各自生成一个随机的初始序列号,并在之后的数据传输中用来标识和确认数据包。
-
防止旧的连接请求对新连接的干扰:
- 三次握手过程中的确认机制可以防止因网络延迟或丢包导致的过期数据包干扰当前通信。
为什么是三次握手而不是两次?
两次握手无法保证双方都知道对方的状态。例如,如果只通过两次握手,客户端发送 SYN 后,服务器发送 SYN-ACK,但如果这个 SYN-ACK 包在传输中丢失,客户端永远不会知道服务器是否准备好,连接可能会出错。而通过第三次握手,服务器能确认客户端已经收到它的响应,确保连接可以顺利进行。
总结
TCP 三次握手确保双方能够可靠地建立连接,保证数据传输的可靠性和有序性,同时防止旧的连接请求影响新的连接。