28-tcp可靠传输——滑动窗口

  前面我们在学习tcp可靠传输时,讲了停止等待和连续ARQ两种可靠传输的协议方式,其中连续ARQ协议还使用了滑动窗口来保证数据的可靠传输和通信效率,可见滑动窗口是非常重要的。

  对于滑动窗口我们可以分成窗口和滑动来进行理解。
  所谓窗口就是一段可以被发送或接收的字节数据,其连续范围称之为“窗口”
  滑动则是这个“可以发送的范围”(也就是窗口)可以在数据的发送过程中而变化的,也就是按照一定的速度滑动。

  如果你现在还是不太理解也没关系,下面将会详细介绍滑动窗口。

28-tcp可靠传输——滑动窗口
图1-分组编号

   在图1中总共有12个分组,每个分组都是100字节,红色数字表示每个分组的序号。比如:第1个分组1 - 100,其中1表示分组的序号,它的分组编号为1。第2个分组的序号是101,编号为2,其他以此类推。这里我们只需记住每个分组的编号和序号就行了,因为我们在讲解滑动窗口中需要用到分组的序号和编号。

   滑动窗口是面向字节流的,为了讲述可靠传输原理方便,我们假设数据传输只在一个方向上进行,即A发送数据,B给出确认。这样我们只讨论两个窗口,即发送方A的发送窗口和接收方的接收窗口。

28-tcp可靠传输——滑动窗口
图2-滑动窗口

   1. 在图2中,A计算机和B计算机在进行数据传输前之前先建立tcp连接,A计算机会根据B计算机的接收窗口的大小400字节,来调整自己的发送窗口,设置为400字节。

   2. A计算机发送应用进程将要传输的800字节数据以字节流写入发送缓冲区,说明有8个分组。第1,2,3,4个分组在发送窗口内(这四个分组是将要发送的数据)。

28-tcp可靠传输——滑动窗口
图3

  3. 在图3中,A计算机将第1,2,3,4四个分组的tcp首部的序号进行填充(第1个分组的tcp首部中的序号为1,第2个分组的tcp首部中的序号为101,其他以此类推),并按顺序发送给B计算机,这时A计算机的发送窗口中的这4个分组在没有收到B的确认,就不能从发送窗口中删除,因为分组丢失或出差错还需要重传。

  4. B计算机将收到的四个分组放入缓存中的接收窗口,按每个分组的tcp首部的序号(seq)进行排序组织,同时接收窗口向前移动并腾出空间接收数据,接收应用进程按顺序读取接收窗口外连续的字节(注意B计算机应用进程从接收缓冲区中读取数据的位置),读取完毕再把数据清除掉(第1,2,3,4,分组)。

  然后B计算机向A计算机发送一个确认,图中大写的ACK = 1代表tcp首部ACK标志位置为1,表示B计算机已经收到A计算机发送的分组数据,其中小写的ack = 401是确认号,该序号有2个作用,一是确认B计算机已经收到401字节前面的数据了,二是期望A计算机下一次开始发送数据的位置是第401个字节。

28-tcp可靠传输——滑动窗口
图4

  5. A计算机收到B计算机的ACK确认包时,得到数据报中tcp首部中的确认号是401,接收窗口为400字节,这时发送窗口向前移动,401后面的字节就进入发送窗口,即第5,6,7,8四个分组进入发送窗口,然后从发送窗口中移出已经确认发送成功的第1,2,3,4四个分组,就可以从缓存中删除掉了,发送应用进程可以向腾出的空间存放后面的字节数据,然后往发送缓冲区中写入第9,10分组。

  然后A计算机在发送第5,6,7,8这四个分组的过程中,由于网络问题导致第7个分组出现丢失或出现错误。

  这时B计算机只能收到第5,6,8三个分组,因为第7个分组已经丢失了,所以B计算机的接收窗口只能向前移200个字节,接收应用程序就可以从接收缓存中读取第5,6分组的字节,读取完毕后将第5,6个分组移出接收窗口,腾出的空间可以被重复利用。

  6. 然后B计算机向A计算机发送一个确认(注意:这是一个选择确认SACK),确认号是601,告诉A计算机已经成功接收到600以前的字节,可以从601个字节开始发送了(因为第七个分组没有接收到)。

注意:tcp在建立连接时,客户端就和服务器协商了是否支持选择确认(SACK),如果都支持选择确认,以后通信过程中发送的确认,除了包含确认号601,同时还包含了已经收到的分组(第8个分组)的边界,这样发送方就不再重复发送第8个分组了,这里大家只需记住就行了,关于选择确认后面会详细介绍,到时候大家再回过头来看滑动窗口就会理解了。

28-tcp可靠传输——滑动窗口
图5

  7. A计算机收到B计算机发送的确认数据包后,发现这是一个选择确认包,然后根据选择tcp首部中的确认号ack = 601,设置发送窗口向前移动了200字节,也就是让窗口滑动到601的位置(601是第七个分组的起始字节的位置),让第9,10个分组就进入发送窗口了,并按顺序发送这两个分组后就停止发送,发送窗口不再向前滑动(因为要重传第7个分组,所以不能再向前滑动)并等待确认B计算机是否有收到第9,10分组,当第7个分组超时后,就重传第7个分组(注意:如果A计算机收到的不是选择确认,那么将重传第7,8分组)。

  8. B计算机收到第9,10分组后,接着又收到了重传的第7分组,接收窗口向前移动,然后接收方应用进程就可以读取接收窗口外的分组数据,读取完毕并把第7,8,9,10分组从接受缓冲区中清除掉,然后B计算机发送确认,将tcp首部中的ACK标志位置1,确认号为1001,相当于告诉A计算机:1001之前的数据已经都接收到了,下一次可以从第1001字节开始发送了。

  9. 同理,A计算机收到B计算机的确认后,发送窗口向前移动,因为发送缓冲区中只有第11,12分组,这时发送窗口中只有200字节数据,A计算机将这两个分组数据发送出去。



  注意:上述只是用画图单纯的介绍滑动窗口技术原理,而实际上滑动窗口是循环利用的,滑动窗口的大小也是会随着网络状况而动态变化的,这里为了方便介绍,没有考虑这些情况(分明就是懒~),所以图中会有一些出入(这也是我强烈建议大家结合书本一起看的原因),但是大家自己一定要分清楚!!!另外,在tcp流量控制,还会再介绍滑动窗口