抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

滑动窗口概念不仅存在于数据链路层,也存在于传输层中,两者有不同的协议,但基本原理上是相近的。其中一个重要的区别是,一个是针对于帧的传送,另外一个是字节数据的传送。

技术介绍

突然有天,你的土豪朋友要给你邮个床,一个超级大豪华床,别问我为什么,任性!

你特别的感动,然后很高兴拒绝了,原因是你在北京住着一个不到五平米的小隔断,床放不下!

通过一个悲催的小例子,我们知道在邮寄东西时,需要考虑接收方的接收能力,不然东西发过去后,收方无法处理。

数据传输也是这个道理,当发送端在发送数据时,如果不考虑网络的情况,直接发送数据,可能数据包的大小超过接收端的接收能力,这个包会被接收端丢掉,变成弃包。

技术图解

而这个接收的能力,就是我们今天要学习的滑动窗口。我们先放一张图片:

看图说话

设 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 秒就发送一个探测报文段,直到窗口重新打开。

这个概念就到这里,有问题的可以在文章下提问。另外以上为个人的理解,欢迎更正指导!

评论