TCP 协议笔记


TCP是主机对主机层的传输控制协议,这个协议主要为了提供可靠的双向连接传输服务。

怎么实现这个可靠的双向连接传输服务?
答案在三次和四次里,协议里设计将连接建立设计为“三次握手”,将释放过程设计为“四次挥手”,为什么这样设计呢?

先了解一些位码(tcp标志位),有6种标示:

  • SYN(synchronous建立联机)
  • ACK(acknowledgement 确认)
  • PSH(push传送)
  • FIN(finish结束)
  • RST(reset重置)
  • URG(urgent紧急)
  • Sequence number(顺序号码)
  • Acknowledge number(确认号码)

流程图:
image

TCP 协议将连接建立设计为“三次握手”,将连接释放设计为“四次挥手”,核心目的是在不可靠的网络环境中实现可靠的双向通信


为什么建立连接需要“三次握手”?

TCP 是全双工协议,意味着双方(客户端 A 和服务端 B)必须同时确认两件事:

  1. A 能发、B 能收
  2. 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)状态:当一方数据发完了,并不代表另一方的数据也发完了。

挥手流程:

  1. 第一次挥手(A \(\rightarrow\) B:FIN):A 表示“我的数据发完了,我要关闭发送通道”。
  2. 第二次挥手(B \(\rightarrow\) A:ACK):B 收到后确认“知道你发完了”,但 B 可能还有未发送完的数据。此时连接处于半关闭状态,A 只能接收,B 仍可发送
  3. 第三次挥手(B \(\rightarrow\) A:FIN):B 的数据也发送完毕后,向 A 发送 FIN,表示“我的数据也发完了,可以关闭发送通道”。
  4. 第四次挥手(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。

  • 清除网络中的旧报文:确保本次连接中的所有滞留数据包都在网络中自然消失,防止新旧连接数据混淆。

posted on 2026-08-25 13:48  Mysticbinary  阅读(10)  评论(0)    收藏  举报