滑动窗口概念不仅存在于数据链路层,也存在于传输层中,两者有不同的协议,但基本原理上是相近的。其中一个重要的区别是,一个是针对于帧的传送,另外一个是字节数据的传送。
技术介绍
突然有天,您的土豪朋友要给您邮个床,一个超级大豪华床,别问杜老师为什么,任性!
您特别的感动,然后很高兴拒绝了,原因是您在北京住着一个不到五平米的小隔断,床放不下!
通过一个悲催的小例子,我们知道在邮寄东西时,需要考虑接收方的接收能力,不然东西发过去后,收方无法处理。
数据传输也是这个道理,当发送端在发送数据时,如果不考虑网络的情况,直接发送数据,可能数据包的大小超过接收端的接收能力,这个包会被接收端丢掉,变成弃包。
技术图解
而这个接收的能力,就是我们今天要学习的滑动窗口。我们先放一张图片:

看图说话
设 A 向 B 发送数据。在连接建立时,B 告诉 A:我的接收窗口是 rwnd=400。
因此,发送方发送窗口不能超过接收方给出的接收窗口的数值。
注意,TCP 窗口单位是字节,非报文段。
再设每一个报文段为 100 字节,而数据报文段序号的初始值设为 1。
大写 ACK 表示首部中的确认位,小写 ack 表示确认字段的值 ack。
图中可以看出,B 进行了三次流量控制。
第一次把窗口减少到 300,第二次又减到了 100,最后是 0,即不允许发送方再发送数据。
这种使发送方暂停发送的状态将持续到主机 B 重新发出一个新窗口值为止。
只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器。
什么是持续计时器?
技术扩展
为了对付零窗口大小的通知,TCP 需要另外一个计时器。
假定接收 TCP 宣布了窗口大小为零。发送 TCP 就会停止传送报文段,直到接收 TCP 发送确认并且宣布一个非零的窗口大小。
但这个确认可能会丢失。我们知道 TCP 中,对确认是不需要发送确认的。
若确认丢失了,接收的 TCP 并不知道,而是会认为它已经完成任务,并等待着发送 TCP 接着会发送更多的报文段。
但发送 TCP 由于没有收到确认,就会等待对方发送确认来通知窗口的大小。双方的 TCP 都在永远地等待着对方。
为了打破这种死锁,TCP 为每一个连接使用一个持续计时器。
当发送 TCP 收到一个窗口大小为零的确认时,就启动持续计时器。
当持续计时器期限到时,发送 TCP 就发送一个特殊的报文段,叫探测报文段。
这个报文段只有一个字节数据。它有一个序号,但它的序号永远不需要确认;甚至在计算对其他部分的数据的确认时该序号也被忽略。
探测报文段是提醒对端:确认已经丢失,必须重传。
持续计时器的值设置为重传时间数值。但是,若是没有收到从接收端来的响应,则需发送另一个探测报文段,并将持续计时器的值加倍和复位。
发送端继续发送探测报文段,将持续计时器设定值加倍和复位,直到这个值增大到门限值止。
在这以后,发送端每 60 秒就发送一个探测报文段,直到窗口重新打开。
这个概念就到这里,有问题的可以在文章下提问。另外以上为个人的理解,欢迎更正指导!