【TCP】TCP的流量控制(TCP滑动窗口和拥塞控制)

目录

TCP滑动窗口和拥塞控制

TCP和UDP的区别

滑动窗口

1. 发送方:

2. 接收方

拥塞控制

慢开始:

拥塞避免:

快重传:

快恢复

流量控制

TCP 协议中的 Window Size与吞吐量

​TCP窗口目的

TCP窗口机制 - 接收窗口「rwnd」

TCP接收窗口「rwnd」大小

​TCP窗口参数设置

TCP接收窗口「rwnd」优化设置​

TCP窗口流量控制​


TCP滑动窗口和拥塞控制

计算机网络第32讲-TCP的流量控制(计算机网络简明教程及仿真实验)

https://www.bilibili.com/video/BV1Lb411G7J1?from=search&seid=10847449054765505085

TCP的拥塞控制(有字幕有背景音乐版)

https://www.bilibili.com/video/BV1kJ41177r8?from=search&seid=5227889908078668427

 

TCP和UDP的区别

1. 有连接和无连接

在这里插入图片描述

 

二、UDP一对一, 一对多和一对全 ,TCP一对一

在这里插入图片描述

 

三、UDP面向报文,TCP面向字节流

在这里插入图片描述

 

四、可靠性

在这里插入图片描述

 

五、报文头信息

在这里插入图片描述

 

小结

在这里插入图片描述

 

引入窗口的原因和swnd、rwnd与cwnd的区别

(摘自:http://youkud.com/m/view.php?id=1596

引入窗口的背景:

最初TCP采用的是每发一个数据,得收到ACK后再发送下一个。这种方式效率比较低下,如果期间出现网络延迟的话会影响下一个数据的发送。为了解决这种问题,TCP引入了窗口的概念。

 

滑动窗口中swnd、rwnd与cwnd的区别:

窗口可以指定大小,而这个大小就是指无需等待确认应答,而可以继续发送数据的最大值

发送端和接收端会各自维护一个自己的窗口,分别是发送窗口(swnd)接受窗口(rwnd)

滑动窗口中swnd、rwnd与cwnd的区别

窗口的大小由谁来决定?

TCP头里有一个window的字段,这个字段是接收端告诉发送端自己有多少缓冲区可以接受数据。发送端会根据这个值来发送数据。所以窗口的大小是根据接收方反馈的信息来决定的。

拥塞控制

当网络出现拥塞时,可能会有大量的数据延迟或者丢失,从而导致触发TCP的重传机制。但是正因为TCP不断地重发,反而会导致网络更加的拥堵。为了避免发送端的数据填满整个网络,TCP有一种机制叫做拥塞控制。

发送端有一个变量叫做拥塞窗口(cwnd),它会根据网络状态而动态的产生变化。和上面滑动窗口里说的发送窗口(swnd)和接受窗口(rwnd)关联起来的话,那么发送窗口=Min(拥塞窗口,接受窗口)

滑动窗口中swnd、rwnd与cwnd的区别

拥塞窗口的变化规则:

网络中没有出现拥塞,cwnd就会增大

网络中有拥塞,cwnd就会减小

如何判断是否有拥塞?发送端是否在规定时间内接收到ACK报文

拥塞控制的四个机制

慢启动

刚开始建立好连接时,cwnd = 1,当接收到ACK后开始增长,指数型增加(1,2,4,8)

当cwnd到达ssthresh阈值后进入拥塞避免

拥塞避免

进入拥塞避免后cwnd的增长速度变成线性增长,每接收一个ACK增长1/cwnd

当触发了重传机制后进入拥塞发生

拥塞发生

既然重传机制分为超时重传和快速重传,那么也有对应的两种解决方法

当发生超时重传时,ssthresh会被重置为cwnd/2,然后cwnd被重置回1。也就是等于重新开始慢启动

当触发快速重传时,cwnd = cwnd/2,ssthresh = cwnd。这里cwnd只被减半,然后进入快速恢复

快速恢复(RFC2581,第五页)

快速恢复开启时,cwnd = ssthresh + 3,并因触发快速重传需要重发丢失的报文

如果还是收到重复ACK,那么cwnd = cwnd + 1

如果收到了新的ACK,那么cwnd = ssthresh,并回到拥塞避免

 

​​​​​​​滑动窗口

1. 发送方:

一个报文的状态:

  • 已经发送,并且收到确认报文(已结束)(窗口外)

  • 已经发送,但还未收到确认报文(等待ACK) (窗口内)

  • 可以发送,但尚未发送(已就绪,等待发送)(窗口内)

  • 不可以发送(受窗口限制,不允许发送) (窗口外)
     

    在这里插入图片描述


    如果出现丢包,那么就会重复对丢包报文前的那个报文进行确认,例如在上图中,如果发送了31,32,33,34,45,其中32丢包,31,33,34,35按序号到达,那么当33到的时候,34到的时候,35到的时候,都是发的对31的确认报文,相当于多发了3次对31的确认报文(当对同一个报文重复确认3次的时候,则会触发快重传)。

    因此,在上图中,31~41一定都是未收到确认的,当31确认收到了以后,那么窗口就会向右滑动,直到最左方的首个元素是“发送了但尚未收到确认报文的” 或者“尚未发送的”。 继续上面这个例子,当31,33,34,35到达,接收方发送了3个对31号报文的ACK,就会触发“快重传”,重新传送32。

2. 接收方

接收方窗口左边为已经发送过的确认报文,右边为当前不能接收的报文。

接收方窗口:

  • 最左边报文一定是尚未收到的报文
  • 如果31没到,32,33先到,就先把32,33缓存在接收缓冲区中,并且会发送2个对30的确认报文,当收到了31的确认报文,那么窗口就继续滑动到34的位置.

在这里插入图片描述


拥塞控制

在理想情况下,随着请求数的增长,网络的吞吐量也会增长,当用户的请求出超出了网络所能承载的负荷时,吞吐量将保持不变。。

而实际情况是,当用户对网络资源的请求数量超过了网路所能抗住的负荷时,吞吐量会随着请求的增多而减少,直到变为0。

在这里插入图片描述


而拥塞控制就是为了防止这一情况的产生,其实现的方式就是,通过调整发送窗口的大小,来控制发送速率,从而起到减少网络流量的作用。

发送方需要维护3个变量( 发送窗口(cwnd), 拥塞窗口(swnd), 窗口阈值(ssthresh)):
实际上,发送方发送窗口大小 = min(拥塞窗口大小(拥塞控制), 接收方接收窗口大小(流量控制))

在这里插入图片描述

拥塞控制包括了4个算法策略分别是:慢开始,拥塞避免,快重传,快恢复。

慢开始:

cwnd = 1, 每发送一轮窗口大小的数据并成功接收到确认报文,就给窗口大小乘2,
当窗口大小超过ssthresh时,使用拥塞避免算法。

拥塞避免:

每发送一轮窗口大小的数据并成功接收到确认报文,就给窗口大小加1,一旦出现超时重传,则判定网络可能出现了拥堵,将cwnd置为1ssthresh变为原来的一半

在这里插入图片描述

快重传:

快重传就是:并不是等超时了才再重传,而是连续收到3个重复的ACK报文时,就开始重传!

在这里插入图片描述

快恢复

快恢复就是:出现了需要重传的情况,并不是把cwnd置为1,而是置成原来大小的一半,(ssthresh也置为原来的一半)。

在这里插入图片描述

在这里插入图片描述


流量控制

流量控制就是,让接收方的发送速率能够匹配上接收方的接收速率,具体实现体现在:控制发送方的发送窗口大小(如果发送的太快了,就把窗口调小点,如果发的太慢了,就把窗口调大点),发送方窗口的大小根据接收方窗口的大小来决定。

实际上,发送方发送窗口大小 = min(拥塞窗口大小(拥塞控制), 接收方接收窗口大小(流量控制))

视频的例子讲的非常棒。

  • 发送方在接收到接收方的确认报文段后,会根据报文中的接收方窗口大小值,来重新调整当前的发送窗口大小。(初始大小在TCP三次握手的时候确定)

  • 发送方窗口可以被设成零。 当发送方窗口大小为0时,会定时发送零窗口探测报文,询问接收方的窗口大小,如果还是0,那么就重置这个定时器,如果不是0就重新调整窗口大小。

  • TCP规定,接收方接收窗口即使为0,也应接收零窗口探测报文,确认报文段,以及携带紧急数据的报文段。

 

 

TCP 协议中的 Window Size与吞吐量

转自:http://blog.sina.com.cn/s/blog_c5c2d6690102wpxl.html

https://www.dazhuanlan.com/2019/12/09/5dee65d87a9c5/

TCP协议中影响实际业务流量的参数很多,这里主要分析一下窗口的影响。

​TCP窗口目的

为了获得最优的连接速率,使用TCP窗口来控制流速率(flow control),滑动窗口就是一种主要的机制。
这个窗口允许源端在给定连接传送数据分段而不用等待目标端返回ACK,一句话描述:

窗口的大小决定在不需要对端响应(acknowledgement)情况下传送数据的数量。

​官方定义:“The amount of octets that can be transmitted without receiving an acknowledgement from the other side”。

TCP窗口机制 - 接收窗口「rwnd」

​​TCP header中有一个Window Size字段,它其实是指接收端的窗口,即接收窗口(「rwnd」),用来告知发送端自己所能接收的数据量,从而达到一部分流控的目的。其实TCP在整个发送过程中,也在度量当前的网络状态,目的是为了维持一个健康稳定的发送过程,比如拥塞控制。因此,数据是在某些机制的控制下进行传输的,就是窗口机制。发送端的发送窗口是基于接收端的接收窗口来计算的,也就是我们常说的TCP是有连接的发送,数据传输需要对端确认,发送的数据分为如下四类来看

窗口滑动发送数据

  • 已经发送并且对端确认(Sent/ACKed):发送窗外缓冲区外
  • 已经发送但未收到确认数据(Sent/UnACKed): 发送窗内缓冲区内​
  • 允许发送但尚未防的数据​(Unsent/Inside): 发送窗内缓冲区内​
  • 未发送暂不允许(Unsent/Outside): 发送窗外缓冲区内​

TCP窗口就是这样逐渐滑动,发送新的数据,滑动的依据就是发送数据已经收到ACK,确认对端收到,才能继续窗口滑动发送新的数据。可以看到窗口大小对于吞吐量有着重要影响,同时ACK响应与系统延时又密切相关。

需要说明的是:

  • 发送端的窗口过大:会引起接收端关闭窗口,处理不过来;
  • 发送端的窗口设置较小:结果就是不能充分利用带宽;

所以仔细调节窗口对于适应不同延迟和带宽要求的系统很重要。

TCP接收窗口「rwnd」大小

最早TCP协议涉及用来大范围网络传输时候,其实是没有超过56Kb/s的​连接速度的。因此,TCP包头中只保留了16bit用来标识窗口大小,允许的最大缓存大小不超过64KB。为了打破这一限制,RFC1323规定了TCP窗口尺寸选择,是在TCP连接开始的时候三步握手的时候协商的(SYN, SYN-ACK, ACK),会协商一个 Window size scaling factor,之后交互数据中的是Window size value,所以最终的窗口大小是二者的乘积.

Window size value: 64 or 0000 0000 0100 0000 (16 bits)
Window size scaling factor: 256 or 2 ^ 8 (as advertised by the 1st packet)

The actual window size is 16,384 (64 window size value * 256 window size scaling factor)

这里的窗口大小就意味着,直到发送16384个字节,才会停止等待对方的ACK.随着双方回话继续,窗口的大小可以修改window size value 参数完成变窄或变宽,但是注意:Window size scaling factor 乘积因子必须保持不变。在RFC1323中规定的偏移(shift count)是14,也就是说最大的窗口可以达到Gbit,很大。

Wireshark抓包实例

这一机制并不总是默认开启的和系统有关,貌似Linux默认开启,Windows默认关闭。

​TCP窗口参数设置

TCP窗口起着控制流量的作用,实际使用时这是一个双端协调的过程,还涉及到TCP的慢启动​(Rapid Increase/Multiplicative Decrease),拥塞避免,拥塞窗口和拥塞控制。可以记住,发送速率是由min(拥塞窗口,接收窗口),接收窗口在下文有讲。

TCP接收窗口「rwnd」优化设置​

TCP接收窗口「rwnd」设置方法

  1. 一个简单的原则是2倍的BDP.这里的BDP的意思是bandwidth-delay
    product
    ,也就是带宽和时延的乘积,带宽对于网络取最差连接的带宽。

    buffer size = 2 * bandwidth * delay​

  2. 还有一种简单的方式,使用ping来计算网络的环回时延(RTT),然后表达为:

    buffer size = bandwidth * RTT​

接收窗口「rwnd」计算方法中为什么是2倍?

因为可以这么想,如果滑动窗口是 bandwidth * delay,当发送一次数据最后一个字节刚到时,对端要回ACK才能继续发送,就需要等待一次单向时延的时间,所以当是2倍时,刚好就能在等ACK的时间继续发送数据,等收到ACK时数据刚好发送完成,这样就提高了效率。

举个例子

带宽是20Mbps,通过ping我们计算单向时延(RTT)是20ms;
可以计算:20000000bps * 8 * 0.02 = 52,428bytes​
因此我们最优窗口用 104,856bytes = 2 x 52,428
所以说当发送者发送 104,856 bytes 数据后才需要等待一个ACK响应,当发送了一半的时候,对端已经收到并且返回ACK(理想情况),等到ACK回来,又把剩下的一半发送出去了,所以发送端就无需等待ACK返回。

发现了么?这里的窗口已经明显大于64KB了,所以机制改善了,上一级。

TCP窗口流量控制​

​现在我们看看到底如何控制流量。TCP在传输数据时和 windows size 关系密切,本身窗口用来控制流量,在传输数据时,发送方数据超过接收方就会丢包,流量控制,流量控制要求数据传输双方在每次交互时声明各自的接收窗口「rwnd」大小,用来表示自己最大能保存多少数据,这主要是针对接收方而言的,通俗点儿说就是让发送方知道接收方能吃几碗饭,如果窗口衰减到零,也就是发送方不能再发了,那么就说明吃饱了,必须消化消化,如果硬撑胀漏了,那就是丢包了。

流量控制

慢启动 ( 拥塞窗口「cwnd」)

虽然流量控制可以避免发送方过载接收方,但是却无法避免过载网络,这是因为接收窗口「rwnd」只反映了服务器个体的情况,却无法反映网络整体的情况。

为了避免网络过载,慢启动引入了拥塞窗口「cwnd」的概念,用来表示发送方在得到接收方确认前,最大允许传输的未经确认的数据。「cwnd」「rwnd」相比不同的是:它只是发送方的一个内部参数,无需通知给接收方,其初始值往往比较小,然后随着数据包被接收方确认,窗口成倍扩大,有点类似于拳击比赛,开始时不了解敌情,往往是次拳试探,慢慢心里有底了,开始逐渐加大重拳进攻的力度。

拥塞窗口扩大

在慢启动的过程中,随着「cwnd」的增加,可能会出现网络过载,其外在表现就是丢包,一旦出现此类问题,「cwnd」的大小会迅速衰减,以便网络能够缓过来。

拥塞窗口与丢包

说明:

网络中实际传输的未经确认的数据大小取决于 min (「rwnd」和「cwnd」)

拥塞避免​ ( 慢启动阈值「ssthresh」)

从慢启动的介绍中,我们能看到,发送方通过对「cwnd」大小的控制,能够避免网络过载,在此过程中,丢包与其说是一个网络问题,倒不如说是一种反馈机制,通过它我们可以感知到发生了网络拥塞,进而调整数据传输策略;
实际上,这里还有一个慢启动阈值 「ssthresh」的概念,

  • 「cwnd」 < 「ssthresh」,那么表示在慢启动阶段;
  • 「cwnd」 > 「ssthresh」,那么表示在拥塞避免阶段,此时「cwnd」不再像慢启动阶段那样呈指数级增长,而是趋向于线性增长,以期避免网络拥塞,此阶段有多种算法实现,通常保持缺省即可,这里就不一一说明了。

如何调整 - 接收窗口「rwnd」

很多时候TCP的传输速率异常偏低,很有可能是接收窗口「rwnd」过小导致,尤其对于时延较大的网络,实际上接收窗口「rwnd」的合理值取决于BDP的大小,也就是带宽和延迟的乘积。假设带宽是 100Mbps,延迟是 100ms,那么计算过程如下:

BDP = 100Mbps 100ms = (100 / 8) (100 / 1000) = 1.25MB​

​此问题下如果想最大限度提升吞度量,接收窗口「rwnd」的大小不应小于 1.25MB。

如何调整 - 拥塞窗口「cwnd」

一般来说「cwnd」的初始值取决于MSS的大小,计算方法如下:

min(4 MSS, max(2 MSS, 4380))

以太网标准的MSS大小通常是1460,所以「cwnd」的初始值是3MSS。当我们浏览视频或者下载软件的时候,「cwnd」初始值的影响并不明显,这是因为传输的数据量比较大,时间比较长,相比之下,即便慢启动阶段「cwnd」初始值比较小,也会在相对很短的时间内加速到满窗口,基本上可以忽略不计。下图使用IxChariot完成一次设置​

设置cwnd

不过当我们浏览网页的时候,情况就不一样了,这是因为传输的数据量比较小,时间比较短,相比之下,如果慢启动阶段「cwnd」初始值比较小,那么很可能还没来得及加速到满窗口,通讯就结束了。这就好比博尔特参加百米比赛,如果起跑慢的话,即便他的加速很快,也可能拿不到好成绩,因为还没等他完全跑起来,终点线已经到了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值