滑动窗口协议(Sliding Window Protocol),属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。
发送方和接收方各自维护着一个缓冲区:发送缓冲区和接收缓冲区,通过商定包的重传机制等一系列操作,来解决传输不可靠的问题。
TCP是传输可靠的,并且采用了返回ACK的机制来保证,那么顺序的发送和接受并ACK效率很低,如下图: 采用这种形式,每次发送一个包,等到对方返回确认收到后,才发送下一个包,这样解决了出错乱序的问题,但是效率很低是显而易见的。
为了缓解上面的问题,提出每次发送多个包,然后对这多个包再依次确认的工作模式:
同时发送多个确实改善了效率低的问题,那么一次发送几个呢?
这种方法真的好吗,吞吐量高吗?更好的方法是,我们可以在发送过去两个包后,收到第一个包的确认后就把第三个包发过去,而不是需要等到收到第二个包的确认后再发送。
图片来源 当前状态: 1-3号,我们无需再理会,4-7是已发送但还未ACK的,8-10是待发送的数据;所以4-10号是当前的发送窗口。
下一时刻: 收到4号的ACK,则将4号从发送窗口剔除,在图中显示为发送窗口的左边界右移,同时发送8-9号数据,将11号数据读入,窗口的右边界右移。 下一时刻 我们已经将5-9号发送,但由于某种原因仍未收到对方的ACK,由于我们已经发送的数据大小是小于的窗口的大小的,即10-11号未发送,这时将10-11号发送过去。 造成迟迟未收到ACK的原因可能是:5-9号包并未真实到达对方或者对方返回的ACK丢失了.
重传窗口数据
发送方有超时定时器,当超过某时间仍未收到ACK则重新发送数据包,这正是为什么已经发送了的数据为什么还要留在发送窗口缓冲区内的原因。
下一时刻 下一次发送方收到了5-8号的ACK,就将窗口左边界右移,右边界右移,发送12-13,并将14-15读入缓冲,接收方回复ACK是要按顺序的,必须要等到5的Ack收到,才会把6-11的Ack发送过去。
当然滑动窗口只是形象上的概念,实际上是数据在移动,而不是物理内存在移动,有了滑动窗口,我们控制了发送数据的多少,也解决了超时重传问题。