TCP的连接管理
三次握手
什么是三次握手?
1. 第一次握手(客户端 → 服务器)
-
客户端发送一个 SYN 报文,请求建立连接。
-
报文中包含一个初始序列号
SEQ = x
。 -
表示:我想和你建立连接,我的序列号是 x。
2. 第二次握手(服务器 → 客户端)
-
服务器收到请求后,回复一个带 SYN 和 ACK 的报文。
-
包含服务器的初始序列号
SEQ = y
和对客户端的确认号ACK = x + 1
。 -
表示:我同意连接,我的序列号是 y,同时确认你发的序列号 x。
3. 第三次握手(客户端 → 服务器)
-
客户端收到服务器的确认后,发送一个 ACK 报文。
-
报文中
SEQ = x + 1
,ACK = y + 1
。 -
表示:我收到你的回应了,一切就绪,我们开始传数据吧。
🤝 举个例子:两个人打电话
你(客户端)想给朋友(服务器)打电话聊天,要确认两件事:
-
你能听到对方的声音
-
对方也能听到你的声音
于是过程是这样的:
✅ 第一次握手:
你打电话说:“喂,你在吗?”(SYN)
—— 你告诉对方:“我准备好了,可以通话。”
✅ 第二次握手:
朋友接到电话,说:“我在,我也准备好了!”(SYN + ACK)
—— 他告诉你:“我听到了你说的话,而且我也准备好了。”
✅ 第三次握手:
你说:“好,我也听到你了,我们开始聊吧!”(ACK)
—— 你再确认一遍:“咱俩都听得见了,正式开始!”
📌 为什么要三次?
-
如果只打两次招呼,比如你说“喂”,对方说“在”,你没回应,那他不知道你到底有没有听到。
-
三次握手让双方都确认彼此听得见,才不会“各说各话”。
四次挥手
① 第一次挥手(主动关闭方发送 FIN 报文)
-
主动关闭方(通常为客户端)发送一个 FIN(Finish)标志位为1 的报文段,表示其已无数据要发送,请求关闭连接。
-
此时,主动方进入 FIN_WAIT_1 状态。
② 第二次挥手(被动关闭方确认 ACK)
-
被动关闭方(通常为服务器)接收到该 FIN 报文后,立即发送一个 ACK 确认报文,确认序号为收到的序列号加一。
-
此时,被动方进入 CLOSE_WAIT 状态,主动方收到 ACK 后进入 FIN_WAIT_2 状态。
-
表示连接的一端(主动方)已关闭发送功能,但仍可接收数据。
③ 第三次挥手(被动关闭方发送 FIN 报文)
-
当被动关闭方确认其数据已发送完毕后,向主动方发送一个 FIN 报文段,请求断开连接。
-
被动方进入 LAST_ACK 状态。
④ 第四次挥手(主动关闭方确认 ACK)
-
主动关闭方接收到该 FIN 报文后,回复一个 ACK 报文,确认序号为收到的序列号加一。
-
然后主动方进入 TIME_WAIT 状态,等待 2 倍最大报文段寿命时间(2MSL)以确保对方收到 ACK。
-
最终,主动方进入 CLOSED 状态,连接完全关闭。
📌 设计四次挥手的原因:
-
TCP 是全双工通信,需要双方分别关闭各自的发送通道,因此每一端都需发送 FIN 和 ACK。
-
四次握手可确保所有未传输完的数据被接收方完整接收,防止数据丢失。
-
引入 TIME_WAIT 状态是为了应对 ACK 报文丢失而可能引起的重复 FIN 报文问题。
🔚 四次挥手是干什么的?
三次握手是“我们开始聊天”,
四次挥手就是“我们聊完了,要挂电话”。
但为什么要挥手四次呢?因为TCP是全双工通信:
客户端和服务器各自都要说一声“我说完了”,所以要四步!
🤝 举个例子:两个人通完电话,要挂断
✅ 第一次挥手(客户端 → 服务器)
你说:“我说完了,不讲了”(FIN=1)
—— 表示你不想再发消息了,但你还能接收对方的消息。
✅ 第二次挥手(服务器 → 客户端)
朋友说:“好的,我知道你说完了。”(ACK = 1)
—— 表示他收到了你的“我说完了”。
✅ 第三次挥手(服务器 → 客户端)
朋友再说:“我也说完了。”(FIN = 1)
—— 表示他也不再发消息了。
✅ 第四次挥手(客户端 → 服务器)
你说:“好的,我知道你也说完了。”(ACK = 1)
—— 表示你收到了他的“我说完了”,双方都确认了。
至此,连接正式断开。
❓为什么不是一次说“咱都不说了”就断?
因为 TCP 要确保双方都“完整地接收了对方要说的最后一句话”。
所以你得等对方也说完,再确认,才能挂电话 —— 这就是四次挥手的意义。
保活计时器(Keep-Alive Timer)
是 TCP 协议中的一种机制,用于检测一个连接是否仍然存活,即使长时间没有数据传输。
✅ 通俗理解:
就像两个人打电话时很久不说话,你会问一句:“你还在吗?”
如果对方不回答,你就知道对方已经断线了。
这就是TCP的保活机制在做的事。
📘 学术定义:
保活计时器(Keep-Alive Timer) 是一种在 TCP 空闲连接期间定期发送探测报文(Keep-Alive Probe)的小型数据包的机制,用以确认对方是否仍保持连接。如果多次发送探测包都未收到响应,则认为连接已断开,并关闭连接。
🔁 工作机制:
-
TCP连接建立后,如果一段时间内没有任何数据传输(默认是2小时),TCP 会启动保活计时器。
-
保活计时器触发后,客户端会发送一个 保活探测包(其实就是一个带 ACK 的空包)。
-
如果服务器:
-
回应了(发送 ACK)→ 连接正常,计时器重新计时。
-
没有回应 → TCP 会重试若干次(如默认5次或10次)。
-
-
连续探测失败 → TCP 判断连接已经断开,关闭连接,通知应用层。