TCP 协议笔记
TCP是主机对主机层的传输控制协议,这个协议主要为了提供可靠的双向连接传输服务。
怎么实现这个可靠的双向连接传输服务?
答案在三次和四次里,协议里设计将连接建立设计为“三次握手”,将释放过程设计为“四次挥手”,为什么这样设计呢?
先了解一些位码(tcp标志位),有6种标示:
- SYN(synchronous建立联机)
- ACK(acknowledgement 确认)
- PSH(push传送)
- FIN(finish结束)
- RST(reset重置)
- URG(urgent紧急)
- Sequence number(顺序号码)
- Acknowledge number(确认号码)
流程图:

TCP 协议将连接建立设计为“三次握手”,将连接释放设计为“四次挥手”,核心目的是在不可靠的网络环境中实现可靠的双向通信。
为什么建立连接需要“三次握手”?
TCP 是全双工协议,意味着双方(客户端 A 和服务端 B)必须同时确认两件事:
- A 能发、B 能收
- B 能发、A 能收
握手流程与能力确认:
- 第一次握手(A \(\rightarrow\) B:SYN):B 收到包,确认“A 能发,B 能收”。
- 第二次握手(B \(\rightarrow\) A:SYN + ACK):A 收到包,确认“B 能发能收,且响应正常”。
- 第三次握手(A \(\rightarrow\) B:ACK):B 收到包,确认“A 能收能发”。
为什么两次不行?
- 防止失效的连接请求突然传到服务端:假设 A 发出的第一个 SYN 包在网络中滞留,A 超时后重传了第二个 SYN 并完成连接。如果只有两次握手,当那个滞留的 SYN 终于到达 B 时,B 会以为 A 又发起新连接并直接建立,但 A 此时根本不理会,导致 B 浪费系统资源等待数据。
- 双方初始化序列号(Seq)需要确认:TCP 传输数据靠序列号去重和排序,双方必须互相告知并确认各自的起始序列号(ISN)。两次握手只能保证单向序列号被确认。
为什么断开连接需要“四次挥手”?
断开连接的过程涉及半关闭(Half-Close)状态:当一方数据发完了,并不代表另一方的数据也发完了。
挥手流程:
- 第一次挥手(A \(\rightarrow\) B:FIN):A 表示“我的数据发完了,我要关闭发送通道”。
- 第二次挥手(B \(\rightarrow\) A:ACK):B 收到后确认“知道你发完了”,但 B 可能还有未发送完的数据。此时连接处于半关闭状态,A 只能接收,B 仍可发送。
- 第三次挥手(B \(\rightarrow\) A:FIN):B 的数据也发送完毕后,向 A 发送 FIN,表示“我的数据也发完了,可以关闭发送通道”。
- 第四次挥手(A \(\rightarrow\) B:ACK):A 回复 ACK 确认,并在等待 2MSL 时间后正式关闭连接。
为什么握手可以三次,挥手却要四次?
- 建立连接时:B 收到 SYN 后,可以将 ACK(应答)和 SYN(同步)合并在同一个包里发送给 A。
- 断开连接时:B 收到 FIN 时,往往还有未处理完的数据或应用层未准备好关闭,因此必须先单独回复 ACK 告诉 A“收到关闭请求”;等自身数据传输完毕后,才能再单独发送 FIN。
关键机制:四次挥手后的 TIME_WAIT(2MSL)
主动关闭连接的一方(通常是 A)在发送完最后一个 ACK 后,必须等待 2MSL(Maximum Segment Lifetime,报文最大生存时间)才彻底释放连接,主要出于两个原因:
-
保证最后一个 ACK 能到达对方:如果最后的 ACK 丢失,B 会重传 FIN。A 在 2MSL 内可以重新收到该 FIN 并重发 ACK。
-
清除网络中的旧报文:确保本次连接中的所有滞留数据包都在网络中自然消失,防止新旧连接数据混淆。
浙公网安备 33010602011771号