TCP 共有 6 个标志位,分别是:
- SYN(synchronous)建立联机。
- ACK(acknowledgement)确认。
- PSH(push)传输。
- FIN(finish)结束。
- RST(reset)重置。
- URG(urgent)紧急。
三次握手
建立3次握手(three-way handshake),需要客户端和服务器总共发送3个包。
- 客户端发送 SYN 标志位的报文,并设置发送序号为 X;
- 服务器发送 ACK 标志位的报文作为确认应答,确认序号为 X + 1;同时发送 SYN 报文,发送序号设置为 Y;
- 客户端发送确认的 ACK 报文,设置确认序号为 Y + 1,发送序号为 X + 1。
四次挥手
- 客户端发送 FIN 报文,用于关闭数据传送;
- 服务端发送 ACK,确认序号为收到的序号加 1。
- 服务端发送 FIN 报文,关闭与客户端的连接;
- 客户端返回 ACK 确认, 并将确认序号设置为收到序号加 1。
从TIME_WAIT 到 CLOSE,为什么等待 2MSL?
Client 发送出最后的 ACK 回复,但该 ACK 可能丢失。Server 如果没有收到 ACK,将不断重复发送 FIN 片段。所以 Client 不能立即关闭,它必须确认Server 接收到了该 ACK。Client 会在发送出 ACK 之后进入到 TIME_WAIT 状态。Client 会设置一个计时器,等待 2MSL 的时间。如果在该时间内再次收到 FIN,那么 Client 会重发 ACK 并再次等待 2MSL。
MSL(Maximum Segment Lifetime)指一个片段在网络中最大的存活时间,2MSL 就是一个发送和一个回复所需的最大时间。如果直到 2MSL,Client 都没有再次收到 FIN,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接。
为什么挥手是 4 次?
可靠的双向通信的最小通信次数是 4 次,建立连接时只有三次握手,是因为中间两次合并了,所以是 3 次;而关闭连接时没有这种合并。那为什么不合并?因为连接的关闭有半关闭状态,不能合并。