TCP滑动窗口

TCP滑动窗口

参考

https://blog.csdn.net/yao5hed/article/details/81046945

https://blog.csdn.net/ligupeng7929/article/details/79597423

https://blog.csdn.net/h2604396739/article/details/85239439

概述

滑动窗口实现了TCP流控制。首先明确滑动窗口的范畴:TCP是双工的协议,会话的双方都可以同时接收和发送数据。TCP会话的双方都各自维护一个发送窗口和一个接收窗口。各自的接收窗口大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。各自的发送窗口则要求取决于对端通告的接收窗口,要求相同。

滑动窗口解决的是流量控制的的问题,就是如果接收端和发送端对数据包的处理速度不同,如何让双方达成一致。接收端的缓存传输数据给应用层,但这个过程不一定是即时的,如果发送速度太快,会出现接收端数据overflow,流量控制解决的是这个问题。

滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小(接收方可以接受缓冲区大小),从而控制发送方的发送速度,不过如果接收端的缓冲区一旦面临数据溢出,窗口大小值也会随之被设置一个更小的值通知给发送端,从而控制数据发送量(发送端会根据接收端指示,进行流量控制)

当接收方设备要求降低或者增大网络流量时,可以对窗口大小进行减小或者增加。当接收方设备要求窗口大小为0,表明接收方已经接收了全部数据,或者接收方应用程序没有时间读取数据,要求暂停发送。发送方接收到携带窗口号为0的确认,停止这一方向的数据传输。

窗口的概念

发送方的发送缓存内的数据都可以被分为4类:

  1. 已发送,已收到ACK
  2. 已发送,未收到ACK
  3. 未发送,但允许发送
  4. 未发送,但不允许发送

其中类型2和3都属于发送窗口。

接收方的缓存数据分为3类:
\1. 已接收
\2. 未接收但准备接收
\3. 未接收而且不准备接收

其中类型2属于接收窗口。

窗口大小代表了设备一次能从对端处理多少数据,之后再传给应用层。缓存传给应用层的数据不能是乱序的,窗口机制保证了这一点。现实中,应用层可能无法立刻从缓存中读取数据。

滑动机制

  1. 发送窗口只有收到发送窗口内字节的ACK确认,才会移动发送窗口的左边界。

  2. 接收窗口只有在前面所有的段都确认的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认。以此确保对端会对这些数据重传。同时实行累计确认,例如:

    发送端发了ABCD,接收端收到了ABD,因为没有收到C,在收到D时只会返回B的ACK(B的ACK内容时C,代表了下一次希望收到的),
    若发送了ABCD全收到,可以只返回D,代表D和D之前的全部收到了

  3. 遵循快速重传、累计确认、选择确认等规则。

  4. 发送方发的window size = 8192;就是接收端最多发送8192字节,这个8192一般就是发送方接收缓存的大小。

窗口大小

img
这里我们可以看到假设窗口的大小是1,也是就每次只能发送一个数据,并且发送方只有接受方对这个数据进行确认了以后才能发送下一个数据。 所以就会存在如下两个问题:

  1. 如果说窗口过小,那么当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。
  2. 如果说窗口的大小定义的过大。我们假设发送方一次发送100个数据。但是接收方只能处理50个数据。这样每次都会只对这50个数据进行确认。发送方下一次还是发送100个数据,但是接受方还是只能处理50个数据。这样就有不必要的数据来拥塞我们的链路。

所以我们就引入了滑动窗口机制,窗口的大小并不是固定的而是根据我们之间的链路的带宽的大小、链路是否拥护塞、接受方是否能处理这么多数据,三个元素共同决定。

img

首先是第一次发送数据这个时候的窗口大小是根据链路带宽的大小来决定的。我们假设这个时候窗口的大小是3。这个时候接受方收到数据以后会对数据进行确认告诉发送方我下次希望手到的是数据是多少。这里我们看到接收方发送的ACK=3(这是发送方发送序列2的回答确认,下一次接收方期望接收到的是3序列信号)。这个时候发送方收到这个数据以后就知道我第一次发送的3个数据对方只收到了2个。就知道第3个数据对方没有收到。下次在发送的时候就从第3个数据开始发。这个时候窗口大小就变成了2
img

这个时候发送方发送2个数据。

img

看到接收方发送的ACK是5就表示他下一次希望收到的数据是5,发送方就知道我刚才发送的2个数据对方收了这个时候开始发送第5个数据。
这就是滑动窗口的工作机制,当链路变好了或者变差了这个窗口还会发生变话,并不是第一次协商好了以后就永远不变了。

模拟动画

模拟特点

找到了一个模拟TCP窗口发送的动画的地址,稍微有缺陷:1. 丢包率如果设得太高,有时无论重发多少次都不能恢复正常 2. 窗口最大可为10,其实应该为9

明确发送端和接收端,发送A~S数据包,我们不会从头到尾分析,因为过程比较长。
\1. 简化了窗口大小,双方窗口大小都一直是4
\2. 设置一定的丢包率,否则没什么值得分析的,包括sender发送的数据包和receiver回复的ACK包。
\3. 简化重传机制,出现丢包则直接重传,不等3个冗余ACK和超时。
\4. 既不是选择重传也不是退回N步,重传的包是随机的

分析滑动窗口机制

  1. 首先发送端发送A,B,C,D四个包,但是A,B丢失,只有C,D到达接收端。
    img
  2. 接收端没有收到A,所以不回复ACK包。发送端重传A,B,C,D四个包,这次全都到达了。
    img
  3. 接收端先获得A,发ACK包A,但是中途丢失;获得B后,根据累计确认的原则,发D的ACK包,然后窗口滑动。再次获得C,D后,连续回复2个D的ACK包,其中C对应的ACK包丢失。
    img
  4. 发送端连收2个D的ACK包,说明4个包对方都已收到,窗口滑动,发E,F,G,H包,其中G包丢失。现在整个序列的状态:ABCD是已发送已确认,EFGH是已发送未确认,I~S是不能发送。
    img
  5. 接收端先收到E,发ACK包;收到F后发F的ACK包;未收到G,还是发F的ACK包;收到H,还是发F的ACK包。不幸的是,三个ACK包全都丢失。
    img
  6. 发送端收到E的ACK包,窗口向右滑动一位;然后再发送F,G,H,I,其中F丢失。
    img
  7. 接收端获得I,因为没有G,只好回复F的ACK包。相继收到G,H包。
    img
  8. 接收端根据累计确认,连发两个I包,其中H对应的丢失。窗口向右滑动。
    img
  9. 发送端接收I的ACK包后,向右滑动四位。发送J,K,L,M四个包,后面不再分析。
    img

从上面的过程中,我们可以得到以下结论:
\1. TCP连接是通过数据包和ACK实现的,我们作为第三者可以看到双方发包的过程,但接受者在收到之前不知道发送方发的是什么,同样的,发送方在收到ACK前也不知道对方是否成功接收。

  1. 发送方没有收到接收方发回的ACK,就不能向右滑动。假设发送方向接收方发了ABCD就滑动,只要对方没收到A,就不能滑动,那么就会出现二者不同步的局面。
  2. 滑动窗口提高了信道利用率,TCP是发送报文段为单位的,假如每发一个报文就要等ACK,那么对于大数据包,等待时间就太长了。只要发送的报文在滑动窗口里面,不用等每个ACK回来就可以向右滑动。本例中,开始接收端空着AB,只有CD,此时不能滑动;之后接收到EF和H,直接向右滑动2位,不必等G到位。
  3. 窗口大小不能大于序号空间大小的一半。目的是为了不让两个窗口出现交迭,比如总大小为7,窗口大小都为4,接收窗口应当滑动4,但只剩3个序号,导致两个窗口交迭。
  4. 有一种情况没出现:发送方发ABCD,接收方都收到然后向右滑动,但回复的ACK包全丢了。发送方未收到任何ACK, timeout后会重发ABCD,此时的接收方按累计确认的原则,收到ABCD后只会重发D的ACK,发送方收到后向右滑动。

对比滑动窗口和拥塞窗口

滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,用于流量控制。拥塞窗口是控制发送速率的,避免发的过多,发送端使用。因为tcp是全双工,所以两边都有滑动窗口。
两个窗口的维护是独立的,滑动窗口主要由接收方反馈缓存情况来维护,拥塞窗口主要由发送方的拥塞控制算法检测出的网络拥塞程度来决定的。

拥塞窗口控制sender向connection传输数据的速率,使这个速率为网络拥堵状况的函数。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值