TCP的SACK(选择性确认)机制详解
字数 1503 2025-11-07 12:33:56

TCP的SACK(选择性确认)机制详解

描述
TCP的SACK(Selective Acknowledgment,选择性确认)是一种优化TCP重传的机制。在标准TCP确认机制中,接收方只能确认连续到达的数据(如确认序号表示之前所有数据已收到),若中间有数据包丢失,发送方需重传所有从丢失包开始的后续数据(即使部分已正确到达),造成带宽浪费。SACK允许接收方明确告知发送方哪些非连续的数据块已成功接收,使发送方仅重传真正丢失的包,提升效率。

知识背景

  • TCP通过确认号(ACK)实现可靠传输:确认号N表示N之前的所有数据已接收。
  • 若数据包乱序或丢失,接收方会重复发送最新ACK(如ACK=N),触发发送方重传(如快速重传)。但标准重传会重传ACK号之后的所有未确认数据,导致冗余。

SACK解决的问题
假设发送方发送序列号1-1000、1001-2000、2001-3000、3001-4000的包:

  • 若包1001-2000丢失,但2001-3000和3001-4000到达接收方。
  • 无SACK时:接收方只能重复发送ACK=1001(确认1001前的数据),发送方需重传1001-4000的所有数据(包括已收到的2001-4000)。
  • 有SACK时:接收方可额外声明“已收到2001-3000和3001-4000”,发送方仅重传1001-2000。

SACK机制详解

  1. 协商启用

    • 在TCP三次握手时,双方在选项字段中携带SACK-Permitted选项(Kind=4),表示支持SACK。
    • 仅当双方均支持时,后续通信才可使用SACK信息。
  2. SACK选项结构

    • 在TCP头部的选项字段中,SACK选项的Kind=5,长度可变。
    • 每个SACK块包含一个连续数据区的起始和结束序列号(左闭右开),如[左边界, 右边界)
    • 一个SACK选项可包含多个SACK块(受TCP选项长度限制,通常最多3-4个块)。
    • 示例:若收到数据段2001-3000和3001-4000,SACK块可表示为[2001, 3001)[3001, 4001)
  3. 接收方行为

    • 当收到非连续数据时,在ACK包中附加SACK选项,报告所有已接收但未确认的数据块。
    • 每次发送ACK时,可更新SACK块内容(如新收到数据块时)。
    • 注意:SACK仅是补充信息,主确认号(ACK号)仍指向连续数据的边界。
  4. 发送方行为

    • 维护一个“SACK表”,记录接收方已确认的数据块。
    • 当检测到丢包(如收到3个重复ACK)时,检查SACK信息:
      • 若SACK块显示某些数据已收到,则跳过这些数据,仅重传未被SACK覆盖的缺失区间。
    • 结合快速重传机制,实现高效恢复。

实例演示
假设发送方发送包:

  • Seq=1:1000(正常确认)
  • Seq=1001:2000(丢失)
  • Seq=2001:3000(到达,触发ACK=1001并携带SACK=[2001,3001))
  • Seq=3001:4000(到达,触发ACK=1001并更新SACK=[2001,3001)和[3001,4001))
    发送方收到3个ACK=1001且SACK显示2001-4000已收到,于是仅重传1001-2000。

SACK的局限性

  • 依赖接收方支持:若一端不支持,则回退为标准TCP。
  • 网络开销:SACK选项增加TCP头大小(尤其多数据块时)。
  • 复杂实现:发送方需维护SACK状态,处理块合并与重叠。

总结
SACK通过显式报告非连续数据块,减少不必要的重传,尤其适合高带宽或高丢包率网络。它是TCP性能优化的重要组成,常与快速重传、拥塞控制协同工作。

TCP的SACK(选择性确认)机制详解 描述 TCP的SACK(Selective Acknowledgment,选择性确认)是一种优化TCP重传的机制。在标准TCP确认机制中,接收方只能确认连续到达的数据(如确认序号表示之前所有数据已收到),若中间有数据包丢失,发送方需重传所有从丢失包开始的后续数据(即使部分已正确到达),造成带宽浪费。SACK允许接收方明确告知发送方哪些非连续的数据块已成功接收,使发送方仅重传真正丢失的包,提升效率。 知识背景 TCP通过确认号(ACK)实现可靠传输:确认号N表示N之前的所有数据已接收。 若数据包乱序或丢失,接收方会重复发送最新ACK(如ACK=N),触发发送方重传(如快速重传)。但标准重传会重传ACK号之后的所有未确认数据,导致冗余。 SACK解决的问题 假设发送方发送序列号1-1000、1001-2000、2001-3000、3001-4000的包: 若包1001-2000丢失,但2001-3000和3001-4000到达接收方。 无SACK时:接收方只能重复发送ACK=1001(确认1001前的数据),发送方需重传1001-4000的所有数据(包括已收到的2001-4000)。 有SACK时:接收方可额外声明“已收到2001-3000和3001-4000”,发送方仅重传1001-2000。 SACK机制详解 协商启用 : 在TCP三次握手时,双方在选项字段中携带 SACK-Permitted 选项(Kind=4),表示支持SACK。 仅当双方均支持时,后续通信才可使用SACK信息。 SACK选项结构 : 在TCP头部的选项字段中,SACK选项的Kind=5,长度可变。 每个SACK块包含一个连续数据区的起始和结束序列号(左闭右开),如 [左边界, 右边界) 。 一个SACK选项可包含多个SACK块(受TCP选项长度限制,通常最多3-4个块)。 示例:若收到数据段2001-3000和3001-4000,SACK块可表示为 [2001, 3001) 和 [3001, 4001) 。 接收方行为 : 当收到非连续数据时,在ACK包中附加SACK选项,报告所有已接收但未确认的数据块。 每次发送ACK时,可更新SACK块内容(如新收到数据块时)。 注意:SACK仅是补充信息,主确认号(ACK号)仍指向连续数据的边界。 发送方行为 : 维护一个“SACK表”,记录接收方已确认的数据块。 当检测到丢包(如收到3个重复ACK)时,检查SACK信息: 若SACK块显示某些数据已收到,则跳过这些数据,仅重传未被SACK覆盖的缺失区间。 结合快速重传机制,实现高效恢复。 实例演示 假设发送方发送包: Seq=1:1000(正常确认) Seq=1001:2000(丢失) Seq=2001:3000(到达,触发ACK=1001并携带SACK= [ 2001,3001)) Seq=3001:4000(到达,触发ACK=1001并更新SACK= [ 2001,3001)和 [ 3001,4001)) 发送方收到3个ACK=1001且SACK显示2001-4000已收到,于是仅重传1001-2000。 SACK的局限性 依赖接收方支持:若一端不支持,则回退为标准TCP。 网络开销:SACK选项增加TCP头大小(尤其多数据块时)。 复杂实现:发送方需维护SACK状态,处理块合并与重叠。 总结 SACK通过显式报告非连续数据块,减少不必要的重传,尤其适合高带宽或高丢包率网络。它是TCP性能优化的重要组成,常与快速重传、拥塞控制协同工作。