TCP的SACK(选择性确认)选项格式与传输中的交互流程详解
字数 1905 2025-12-09 18:51:04

TCP的SACK(选择性确认)选项格式与传输中的交互流程详解

描述
TCP的SACK(Selective Acknowledgment,选择性确认)是一种在TCP连接中优化重传的机制。传统TCP使用累积确认(Cumulative ACK),只能确认连续接收的数据,若发生非连续数据段丢失,发送方需重传所有未被确认的数据(即使部分数据已正确接收)。SACK允许接收方通过SACK选项,在ACK报文中告知发送方已接收的非连续数据块,从而让发送方仅重传缺失的数据段,提高传输效率。


1. SACK选项格式
SACK选项是TCP头部可选字段之一,格式如下:

  • 类型(Kind):1字节,固定为5,表示这是一个SACK选项。
  • 长度(Length):1字节,指示SACK选项的总字节数(包括Kind和Length字段)。每个SACK块占8字节,长度值 = 2 + 8 × SACK块数。
  • SACK块列表:每个SACK块包含两个32位边界:
    • 左边界:已接收数据块的起始序列号(不含该序号,即第一个未接收的序列号)。
    • 右边界:已接收数据块的结束序列号(含该序号减一,即最后一个已接收的序列号+1)。
      注意:SACK块描述的是已接收的数据范围,且通常与ACK字段的累积确认序列号结合使用。

示例:
若ACK=5001,SACK块=[5001, 6001),表示序列号5000之前的数据已确认,且序列号5000-6000(不含6000)的数据块已接收但非连续。


2. SACK协商与启用
SACK在TCP三次握手阶段通过选项协商:

  • 双方在SYN或SYN-ACK报文中携带SACK-permitted选项(Kind=4,Length=2),表示支持SACK。
  • 只有双方都声明支持SACK,后续数据传输中才能使用SACK选项。

3. 数据传输中的SACK交互流程
假设发送方发送序列号1001-2000、2001-3000、3001-4000三个数据段,并发生非连续丢失:

步骤1:正常发送与部分接收

  • 接收方正确收到1001-2000和3001-4000,但2001-3000丢失。
  • 接收方发送ACK=2001(累积确认,期望下一个序列号),并携带SACK选项:SACK块=[3001, 4001)
    含义:确认了1001-2000的数据,并告知发送方“3001-4000已收到,但2001-3000缺失”。

步骤2:发送方处理SACK信息

  • 发送方维护“SACK接收数据图”,记录已被SACK确认的非连续数据块。
  • 根据ACK=2001,发送方知道2001之前的数据已确认,但2001-3000未确认。
  • SACK块[3001,4001)表明3001-4000已接收,因此发送方仅需重传2001-3000。

步骤3:重传与后续确认

  • 发送方重传2001-3000后,接收方收到该段,数据变为连续(1001-4000)。
  • 接收方发送ACK=4001(累积确认),无需携带SACK选项。

4. 多个SACK块的处理
若接收方有多个非连续数据块,可在同一ACK中携带最多4个SACK块(受TCP选项长度限制,通常最多4块)。
示例:

  • 接收数据:1001-2000、3001-4000、5001-6000(缺失2001-3000、4001-5000)。
  • ACK=2001,SACK块=[3001,4001)、[5001,6001)。
  • 发送方重传2001-3000后,接收方ACK=4001,SACK块=[5001,6001)(剩余一个非连续块)。

5. SACK与重传超时(RTO)的协同

  • 当发生丢包时,SACK可触发快速重传(基于重复ACK),无需等待超时。
  • 发送方根据SACK信息更新“重传队列”,仅重传未被SACK覆盖的缺失数据段。
  • 若网络拥塞严重,SACK可能多次重复同一数据块信息,发送方需结合拥塞控制算法(如NewReno或CUBIC)调整拥塞窗口。

6. SACK的局限性

  • 资源开销:发送方需维护SACK数据图,增加内存与计算负担。
  • ACK丢失:若携带SACK的ACK丢失,发送方可能无法及时更新接收状态,但可通过后续SACK恢复。
  • 与旧协议兼容:仅当两端支持SACK时生效,否则回退到累积确认。

总结
SACK通过允许接收方“选择性确认”非连续数据,显著减少了不必要的重传,尤其在多个数据段丢失时提升性能。其核心在于SACK选项格式的设计、握手阶段的协商,以及发送方对SACK信息的实时处理。结合快速重传与拥塞控制,SACK成为现代TCP实现高可靠传输的关键机制之一。

TCP的SACK(选择性确认)选项格式与传输中的交互流程详解 描述 TCP的SACK(Selective Acknowledgment,选择性确认)是一种在TCP连接中优化重传的机制。传统TCP使用累积确认(Cumulative ACK),只能确认连续接收的数据,若发生非连续数据段丢失,发送方需重传所有未被确认的数据(即使部分数据已正确接收)。SACK允许接收方通过SACK选项,在ACK报文中告知发送方已接收的非连续数据块,从而让发送方仅重传缺失的数据段,提高传输效率。 1. SACK选项格式 SACK选项是TCP头部可选字段之一,格式如下: 类型(Kind) :1字节,固定为 5 ,表示这是一个SACK选项。 长度(Length) :1字节,指示SACK选项的总字节数(包括Kind和Length字段)。每个SACK块占8字节,长度值 = 2 + 8 × SACK块数。 SACK块列表 :每个SACK块包含两个32位边界: 左边界 :已接收数据块的起始序列号(不含该序号,即第一个未接收的序列号)。 右边界 :已接收数据块的结束序列号(含该序号减一,即最后一个已接收的序列号+1)。 注意 :SACK块描述的是已接收的数据范围,且通常与ACK字段的累积确认序列号结合使用。 示例: 若ACK=5001,SACK块= [ 5001, 6001),表示序列号5000之前的数据已确认,且序列号5000-6000(不含6000)的数据块已接收但非连续。 2. SACK协商与启用 SACK在TCP三次握手阶段通过选项协商: 双方在SYN或SYN-ACK报文中携带 SACK-permitted 选项(Kind=4,Length=2),表示支持SACK。 只有双方都声明支持SACK,后续数据传输中才能使用SACK选项。 3. 数据传输中的SACK交互流程 假设发送方发送序列号1001-2000、2001-3000、3001-4000三个数据段,并发生非连续丢失: 步骤1:正常发送与部分接收 接收方正确收到1001-2000和3001-4000,但2001-3000丢失。 接收方发送ACK=2001(累积确认,期望下一个序列号),并携带SACK选项: SACK块=[3001, 4001) 。 含义 :确认了1001-2000的数据,并告知发送方“3001-4000已收到,但2001-3000缺失”。 步骤2:发送方处理SACK信息 发送方维护“SACK接收数据图”,记录已被SACK确认的非连续数据块。 根据ACK=2001,发送方知道2001之前的数据已确认,但2001-3000未确认。 SACK块 [ 3001,4001)表明3001-4000已接收,因此发送方仅需重传2001-3000。 步骤3:重传与后续确认 发送方重传2001-3000后,接收方收到该段,数据变为连续(1001-4000)。 接收方发送ACK=4001(累积确认),无需携带SACK选项。 4. 多个SACK块的处理 若接收方有多个非连续数据块,可在同一ACK中携带最多4个SACK块(受TCP选项长度限制,通常最多4块)。 示例: 接收数据:1001-2000、3001-4000、5001-6000(缺失2001-3000、4001-5000)。 ACK=2001,SACK块= [ 3001,4001)、 [ 5001,6001)。 发送方重传2001-3000后,接收方ACK=4001,SACK块= [ 5001,6001)(剩余一个非连续块)。 5. SACK与重传超时(RTO)的协同 当发生丢包时,SACK可触发快速重传(基于重复ACK),无需等待超时。 发送方根据SACK信息更新“重传队列”,仅重传未被SACK覆盖的缺失数据段。 若网络拥塞严重,SACK可能多次重复同一数据块信息,发送方需结合拥塞控制算法(如NewReno或CUBIC)调整拥塞窗口。 6. SACK的局限性 资源开销 :发送方需维护SACK数据图,增加内存与计算负担。 ACK丢失 :若携带SACK的ACK丢失,发送方可能无法及时更新接收状态,但可通过后续SACK恢复。 与旧协议兼容 :仅当两端支持SACK时生效,否则回退到累积确认。 总结 SACK通过允许接收方“选择性确认”非连续数据,显著减少了不必要的重传,尤其在多个数据段丢失时提升性能。其核心在于SACK选项格式的设计、握手阶段的协商,以及发送方对SACK信息的实时处理。结合快速重传与拥塞控制,SACK成为现代TCP实现高可靠传输的关键机制之一。