TCP的SACK(选择性确认)机制详解
字数 1303 2025-11-08 10:03:28
TCP的SACK(选择性确认)机制详解
1. 问题背景:TCP确认机制的局限性
TCP通过确认号(ACK)实现可靠传输:接收方返回的ACK号表示“该序号之前的所有数据已接收成功”。但传统ACK存在缺陷:当多个数据段中间部分丢失时(例如发送1-1000、1001-2000、2001-3000三个段,仅1001-2000丢失),接收方只能返回ACK=1001(重复确认第一个段),发送方无法知道后续2001-3000是否被正确接收,只能重传1001-2000及之后所有数据(即使2001-3000已到达),造成带宽浪费。
2. SACK的核心思想
SACK(Selective Acknowledgment)允许接收方在ACK报文中额外携带“已成功接收的非连续数据块范围”,发送方据此仅重传真正丢失的数据段,避免不必要的重传。
3. SACK的协商与报文格式
- 协商过程:在TCP三次握手时,双方在SYN报文中通过
TCP Option声明支持SACK(选项类型为4)。若两端均支持,后续通信可启用SACK。 - 报文格式:
- 接收方在ACK报文中添加
SACK Option(选项类型为5),结构为[左边界1, 右边界1], [左边界2, 右边界2], ...,每个边界为4字节序号。 - 例如:若接收方已收到1-1000、2001-3000、4001-5000三个数据块,但1001-2000丢失,SACK选项将包含
[2001, 3001]和[4001, 5001](右边界为最后字节序号+1)。
- 接收方在ACK报文中添加
4. 发送方处理SACK的逻辑
发送方维护一个“发送队列”记录已发送但未确认的数据段。当收到SACK时:
- 解析SACK块,标记对应数据段为“已接收”。
- 结合ACK号(如ACK=1001)确定丢失范围:ACK号之后第一个未在SACK中出现的连续数据段即为丢失段(本例中1001-2000未被SACK覆盖,需重传)。
- 仅重传缺失段,保留已成功传输的后续数据(如2001-3000和4001-5000)。
5. SACK与快速重传的协同
- 当发送方收到3个重复ACK(如连续收到ACK=1001)时,触发快速重传机制。
- 若同时携带SACK信息(如SACK=[2001,3001]),发送方直接重传1001-2000,无需等待超时计时器,进一步提升效率。
6. SACK的局限性
- 网络开销:SACK选项增加报文头部大小(最多可携带4个SACK块,占40字节)。
- 发送方复杂度:需维护更精细的数据段状态,可能增加CPU负担。
- 中间设备干扰:某些防火墙或NAT设备可能丢弃SACK选项,导致回退到传统ACK模式。
7. 实际应用中的优化
- SACK压缩:当SACK块过多时,接收方可优先报告最近接收的数据块,避免选项过长。
- 与DSACK结合:DSACK(Duplicate SACK)允许接收方报告重复接收的数据段,帮助发送方判断重传是否冗余(如因ACK丢失导致的误重传)。
通过SACK机制,TCP在乱序或部分丢包场景下显著减少了重传量,尤其适用于高延迟、高丢包率的网络环境(如无线网络)。