1.四次握手的过程
-
客户端A发送 FIN(终止连接请求)
- A:我要断开连接了(
FIN
)。 - A进入FIN_WAIT_1状态,表示请求断开,等待对方确认。
- A:我要断开连接了(
-
服务器B回复 ACK(确认断开请求,但还未准备好关闭)
- B:我收到了你的断开请求,但我还有数据要处理,你先等一下(
ACK
)。 - B进入CLOSE_WAIT状态,A进入FIN_WAIT_2状态,A此时不会再发送数据,但会继续接收。
- B:我收到了你的断开请求,但我还有数据要处理,你先等一下(
-
服务器B处理完数据后,发送 FIN(关闭请求)
- B:我也准备好断开了,我们可以关闭连接(
FIN
)。 - B进入LAST_ACK状态,等待客户端的最终确认。
- B:我也准备好断开了,我们可以关闭连接(
-
客户端A回复 ACK(确认断开完成)
- A:好的,连接断开(
ACK
),正式关闭连接。 - A进入TIME_WAIT状态,等待一段时间确保B已收到ACK,之后真正关闭。B收到ACK后直接关闭连接。
- A:好的,连接断开(
2.为啥不是三次(确保数据完整交付)
假设三次挥手的流程如下:
- A 发送
FIN
,请求关闭连接。 - B 立即发送
FIN+ACK
,表示确认并关闭连接。 - A 直接关闭连接。
问题:
- 由于B可能仍有未完成的数据需要发送,A的过早关闭会导致数据丢失。
- B应该在确认A的请求(
ACK
)后,先完成自己要发送的数据,再主动请求关闭(发送FIN
)。 - 三次挥手无法区分“确认收到断开请求 和 我也准备断开””这两个不同的操作,因此需要额外的一次握手。
总结:TCP 需要四次挥手,而不能三次的原因是:
- TCP是全双工通信,双方的发送和接收是独立的,必须各自关闭。
- 确保数据的完整性,避免提前关闭连接导致数据丢失。
- 防止“半关闭”状态时误断开,导致连接数据未完整发送。