摘要

  • TCP 头部始终包含确认号字段,但只有 ACK 置位时该字段才有意义。
  • 该数值表示发送方期待的下一个序号,并累计确认此前的序号位置。
  • 三次握手展示了这一转换:初始 SYN 不带有效确认,SYN,ACK 则使确认号开始表达对端状态。

字段存在,不代表它正在说话

RFC 793 和 RFC 9293 采用固定的 TCP 头部布局。初始 SYN、数据段和连接结束阶段都保留同一个 32 位确认号字段。但接收方不能仅因字段存在就解释它。规范规定,只有 ACK 控制位置位时,该字段才包含发送方期待接收的下一个序号。RFC 9293 将 ACK 简洁地定义为“确认字段有效”。

因此,主动打开连接的一方可以先宣布自己的初始序号,而不必伪造已经收到对端序号的印象。ACK 清零时,字段仍在头部,却不构成确认证据。协议用一个固定格式保留空间,把语义交给连接状态决定。

握手让意义的变化可见

RFC 9293 的基本示例中,第一段为 SEQ=100、CTL=SYN,没有 ACK。对端回复 SEQ=300、ACK=101、CTL=SYN,ACK。最后一段为 SEQ=101、ACK=301、CTL=ACK。由于 SYN 会占用一个序号位置,确认 100 就意味着下一个期待值为 101。

同一个头部布局由此跨过语义边界:在第一个 SYN 中,确认号不具有协议意义;在 SYN,ACK 中,ACK 使它成为对端状态的证据;连接建立后,确认在该状态下总是发送。这里改变的不是字段位置,而是字段是否得到协议授权来表达意义。

它标记的是边界,不是应用回执

确认号表示下一个期待的序号,因此累计确认此前连续的序号位置。它不是收到的每个报文清单,也不证明对端身份或应用已经处理数据。窗口字段则说明从该确认号开始,发送方愿意接受多少数据八位组。两者相邻而相关,但只有 ACK 是确认字段的意义开关。

ACK 本身不占用序号空间。否则,对端就必须继续确认确认报文,形成递归的记账问题。正因为 ACK 不推进序号,已建立连接的报文才能把累计接收状态附在数据上,或在没有新数据时更新这一边界。

从 1981 年延续至今

RFC 793 与现行标准 RFC 9293 保留了同一结构:固定的 32 位字段、由 ACK 条件性激活的意义、累计确认,以及不为 ACK 分配序号。这是协议结构上的结论,而不是对现代实现行为的判断。

来源