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机制详解
-
协商启用:
- 在TCP三次握手时,双方在选项字段中携带
SACK-Permitted选项(Kind=4),表示支持SACK。 - 仅当双方均支持时,后续通信才可使用SACK信息。
- 在TCP三次握手时,双方在选项字段中携带
-
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性能优化的重要组成,常与快速重传、拥塞控制协同工作。