找回密码
 注册
搜索
热搜: 超星 读书 找书
查看: 421|回复: 2

[【求助】] 关于TCP协议的SACK选项功能详细解读

[复制链接]
发表于 2007-4-26 13:31:42 | 显示全部楼层 |阅读模式
1. 前言

  TCP通信时,如果发送序列中间某个数据包丢失,TCP会通过重传最后确认的包开始的后续包,这样原先已经正确传输的包也可能重复发送,急剧降低了TCP性能。为改善这种情况,发展出SACK(Selective Acknowledgment, 选择性确认)技术,使TCP只重新发送丢失的包,不用发送后续所有的包,而且提供相应机制使接收方能告诉发送方哪些数据丢失,哪些数据重发了,哪些数 据已经提前收到等。

  2. SACK选项

  SACK信息是通过TCP头的选项部分提供的,信息分两种,一种标识是否支持SACK,是在TCP握手时发送;另一种是具体的SACK信息。

  2.1 SACK允许选项

         类型值: 4
    +---------+---------+
    | Kind=4 | Length=2|
    +---------+---------+

  该选项只允许在有SYN标志的TCP包中,也即TCP握手的前两个包中,分别表示各自是否支持SACK。

  2.2 SACK选项

  选项类型: 5

  选项长度: 可变,但整个TCP选项长度不超过40字节,实际最多不超过4组边界值。

             +--------+--------+
             | Kind=5 | Length |
    +--------+--------+--------+--------+
    |   Left Edge of 1st Block    |
    +--------+--------+--------+--------+
    |   Right Edge of 1st Block   |
    +--------+--------+--------+--------+
    |                  |
    /      . . .         /
    |                  |
    +--------+--------+--------+--------+
    |   Left Edge of nth Block    |
    +--------+--------+--------+--------+
    |   Right Edge of nth Block   |
    +--------+--------+--------+--------+

  该选项参数告诉对方已经接收到并缓存的不连续的数据块,注意都是已经接收的,发送方可根据此信息检查究竟是哪个块丢失,从而发送相应的数据块。

  * Left Edge of Block

  不连续块的第一个数据的序列号。

  * Right Edge of Block

  不连续块的最后一个数据的序列号之后的序列号。表示(Left Edge - 1)和(Right Edge)处序列号的数据没能接收到。

  3. SACK的产生
回复

使用道具 举报

 楼主| 发表于 2007-4-26 13:32:26 | 显示全部楼层
SACK通常都是由TCP接收方产生的,在TCP握手时如果接收到对方的SACK允许选项同时自己也支持SACK的话,在接收异常时就可以发送SACK包通知发送方。

  3.1 对中间有丢包或延迟时的SACK

  如果TCP接收方接收到非期待序列号的数据块时,如果该块的序列号小于期待的序列号,说明是网络复制或重发的包,可以丢弃;如果收到的数据块序列号大于期待的序列号,说明中间包被丢弃或延迟,此时可以发送SACK通知发送方出现了网络丢包。

  为反映接收方的接收缓存和网络传输情况,SACK中的第一个块必须描述是那个数据块激发此SACK选项的,接收方应该尽可能地在SACK选项部分中填写尽可能多的块信息,即使空间有限不能全部写完,SACK选项中要报告最近接收的不连续数据块,让发送方能了解当前网络传输情况的最新信息。

  3.2 对重发包的SACK(D-SACK)

  RFC2883中对SACK进行了扩展,在SACK中描述的是收到的数据段,这些数据段可以是正常的,也可能是重复发送的,SACK字段具有描述重复发送的数据段的能力,在第一块SACK数据中描述重复接收的不连续数据块的序列号参数,其他SACK数据则描述其他正常接收到的不连续数据,因此第一块SACK描述的序列号会比后面的SACK描述的序列号大;而在接收到不完整的数据段的情况下,SACK范围甚至可能小于当前的ACK值。通过这种方法,发送方可以更仔细判断出当前网络的传输情况,可以发现数据段被网络复制、错误重传、ACK丢失引起的重传、重传超时等异常的网络状况。

  4. 发送方对SACK的响应

  TCP发送方都应该维护一个未确认的重发送数据队列,数据未被确认前是不能释放的,这个从重发送队列中的每个数据块都有一个标志位“SACKed”标识是否该块被SACK过,对于已经被SACK过的块,在重新发送数据时将被跳过。发送方接收到接收方SACK信息后,根据SACK中数据标志重发送队列中相应的数据块的“SACKed”标志,但如果接收不到接收方数据,超时后,所有重发送队列中数据块的SACKed位都要清除,因为可能接收方已经出现了异常。

  5. SACK应用举例

  发送方发 接收方接 接收方发送的ACK

  送的数据 收的数据 (包括SACK)

  5.1 SACK累加接收的数据

    5000-5499   (该包丢失)
    5500-5999   5500-5999  5000, SACK=5500-6000
    6000-6499   6000-6499  5000, SACK=5500-6500
    6500-6999   6500-6999  5000, SACK=5500-7000
    7000-7499   7000-7499  5000, SACK=5500-7500
回复

使用道具 举报

 楼主| 发表于 2007-4-26 13:33:00 | 显示全部楼层
5.2 数据包丢失,ACK丢失

    3000-3499   3000-3499  3500 (ACK包丢失)
    3500-3999   3500-3999  4000 (ACK包丢失)
    4000-4499   (该包丢失)
    4500-4999   4500-4999  4000, SACK=4500-5000 (ACK包丢失)
    3000-3499   3000-3499  4000, SACK=3000-3500, 4500-5000
                        ---------此为D-SACK

  5.3 数据段丢失和延迟

    500-999    500-999   1000
    1000-1499   (延迟)
    1500-1999   (该包丢失)
    2000-2499   2000-2499  1000, SACK=2000-2500
    1000-2000   1000-1499  1500, SACK=2000-2500
    1000-2000  2500, SACK=1000-1500
                        ---------此为D-SACK

  5.4 数据段丢失且延迟

     500-999    500-999   1000
     1000-1499   (延迟)
     1500-1999   (该包丢失)
     2000-2499   (延迟)
     2500-2999   (该包丢失)
     3000-3499   3000-3499  1000, SACK=3000-3500
     1000-2499   1000-1499  1500, SACK=3000-3500
     2000-2499  1500, SACK=2000-2500, 3000-3500
     1000-2499  2500, SACK=1000-1500, 3000-3500
                        ---------此为部分D-SACK

  6. 结论

  通过SACK选项可以使TCP发送方只发送丢失的数据而不用发送后续全部数据,提高了数据的传输效率。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|网上读书园地

GMT+8, 2024-9-23 11:28 , Processed in 0.134496 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表