TCP滑动窗口

TCP滑动窗口

目录

  • 以字节流为单位的滑动窗口
  • TCP数据流的类别
  • 接收窗口的确认机制
  • 窗口缩放
  • 缓冲区
  • 超时重传时间的选择
  • 选择确认SACK

以字节流为单位的滑动窗口

现假定A收到B发来的确认报文,其中窗口是20,而确认号为31.根据这两个数据,A就构造出了自己的发送窗口:

  • 在没有收到B的确认的情况下,A可以连续把窗口内的数据都发送出去.凡是已经发送过去的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用.
  • 窗口后沿的后面部分表示已经确认接收.这些数据不需要再保留了.
  • 窗口的前沿部分表示不允许发送,因为接收方都没有为这部分数据保留缓存空间.

TCP数据流的类别

现在假定A发送序号为31到41的数据.此时, 发送窗口位置并未改变,如图:

从上图,可以得来的信息:

小于P1的是已经发送并已经收到确认的部分.而大于P3的是不允许发送的部分.
P3-P1 = A 的发送窗口.

P2-P1 = 已发送但尚未确认的字节数

P3-P2 = 允许发送但尚未发送的字节数.又称为可用窗口.

接收窗口的确认机制

B的接收窗口大小是20. 在接收窗口外面,到30号为止的数据是已经发送过确认.接收窗口内的序号31~50是允许接收的. 下图:

B收到了序号为32和33的数据.这些数据没有按序到达,因为序号31还没有到达.此时,B只能对按序到达的数据中的最高序号给出确认,因此B发送的确认报文段中的确认号仍然为31.

窗口缩放

现在假定B收到了序号为31的数据,并把序号为31~33的数据交付主机,然后B删除这些数据.接着把接收窗口向前移动3个序号,如下图:

同时给A发送确认,其中窗口值为20,但确认号为34.我们注意到, B收到了序号为37,38,40的数据,但这些数据没有按序到达,只能暂时存放在接收窗口中.

A收到B的确认后,就可以把发送窗口向前移动3个序号,但指针P2不动.可以看出,现在A的可用窗口增大了.

A在继续发送完序号42~53的数据后,指针P2和P3重合.发送窗口内的序号已经用完,但还没有收到确认.这时A必须停止发送.如果一段时间后,A还没有收到B发来的确认,那么A必须重传这部分数据.

缓冲区

上图中,我们可以看到:

  • 接收端LastByteRead指向了TCP缓冲区中读到的位置,NextByteExpected指向的地方是收到的连续包的最后一个位置,LastByteRcved指向的是收到的包的最后一个位置,我们可以看到中间有些数据还没有到达,所以有数据空白区。

  • 发送端的LastByteAcked指向了被接收端Ack过的位置(表示成功发送确认),LastByteSent表示发出去了,但还没有收到成功确认的Ack,LastByteWritten指向的是上层应用正在写的地方。

超时重传时间的选择

由于TCP的下层是互联网环境, 发送的报文段可能经过一个高速率的局域网, 也可能经过多个低速率的网络.如果把超时重传时间设置得太短, 就会引起很多报文的不必要重传. 如果把超时重传的时间设置得过长, 则会使得网络的空闲时间太长,从而降低了传输效率.

TCP采用了一种自适应的算法, 它记录一个报文段的发出时间, 以及收到相应的确认时间.这两个时间之差就是报文段的往返时间 RTT. TCP保留了RTT的一个加权平均往返时间RTTs.每当第一次测量到样本RTT样本时,RTTs的值就取为所测量到的RTT样本值.但以后每测量到一个新的RTT样本时,就按照下面的公式计算RTTs:

新的RTTs = (1 - a) (旧的RTTs) + a (新的RTT样本)

RFC推荐a的值为1/8.用这种方法测出的加权平均往返时间RTTs会比测量的RTT值更加平滑.

显然超时重传时间应略大于RTTs. RCF推荐使用下面公式计算:

RTO = RTTs+= + 4 * RTTD

RTTD是RTT的偏差加权平均值,它与RTTs和新的RTT样本的差有关.当第一次测量时, RTTD取为测量到的RTT样本值的一半.在以后的测量中,可以使用下面的公式计算出RTTD

新的RTTD = (1 - B) (旧的RTTD) + B |RTTs - 新的RTT样本 |

选择确认SACK

现在假设接收方收到的报文段无差错, 只是未按序号,中间还缺少一些序号的数据,通过选择确认SACK可以实现只传送缺少的数据而不重传已经正确到达接收方的数据.下面使用一个例子来理解SACK的工作原理.

TCP接收方在接收对方发送过来的数据字节流的序号不连续,结果就形成了不连续的字节块:

从上图可以看出, 序号1~1000收到了,但序号1001~1500没有收到,接下来的字节又收到了,但是缺少3001~3500.后面序号4501起也没有收到.换句话说,接收方收到了和前面的字节流不连续的两个字节块.如果这些字节块都在接收窗口的范围内,那么接收方就先收下这些数据,但要把这些信息发给发送方,防止发送方重传接收方已经接收到的数据.

参考资料

计算机网络(谢希仁)
http://coolshell.cn/articles/11609.html

分享到