• 计算机网络:运输层 - TCP 流量控制 & 拥塞控制



    滑动窗口

    如图所示:

    在这里插入图片描述

    TCP首部中有一个窗口字段,该字段就基于滑动窗口来辅助流量控制拥塞控制。所以我们先讲解滑动窗口。

    首先,发送方会维护一个发送缓存

    在这里插入图片描述

    应用程序会把想要发送的数据写入到发送缓存中,而在发送缓存内部,维护一个发送窗口

    发送窗口将发送缓存分为四个部分:

    在这里插入图片描述

    当发送方发送数据后,就要等待对方确认,粉色区域就是发送了但是没有收到确认的区域。当粉色区域的字节收到确认后,就会离开滑动窗口,进入绿色区域。

    蓝色区域的字节,是可以发送的但是还没有发送,一旦发送了就进入粉色区域,等待确认。黄色区域处于发送缓存但不处于发送窗口,此时是待发送的数据,但是还不能发送。

    接收方也会维护一个接收缓存

    在这里插入图片描述

    接收缓存也被接收窗口划分为了三个部分:

    在这里插入图片描述

    接收窗口内部的数据,是允许接收的,当接收到一个数据接收到后,接收方对其发出确认,随后该数据变成绿色部分,即已经确认接收的部分。黄色部分则是不允许接收的部分,就算收到这个区域的数据,也会被丢弃。

    滑动窗口的运行模式如下:

    一开始A发送了313233这三个报文,但是31丢失了:

    在这里插入图片描述

    由于3233在接收窗口内,可以正常接收,但是由于31没有收到,此时接收窗口不能往后移动。

    随后B发送确认报文,确认号为31,表示当前收到的最后一个连续报文是31,虽然3334也收到了,但是不连续

    在这里插入图片描述

    由于一直没收到31的确认报文,A超时重传31

    在这里插入图片描述

    随后B就收到了这三个连续的报文,于是接收窗口向后滑动:

    在这里插入图片描述

    B又发送确认号为34的报文,表示33之前的所有报文都收到了,此时A的发送窗口也向后移动:

    在这里插入图片描述


    流量控制

    流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。其本质是通过控制滑动窗口的大小来实现的。

    每个TCP数据报发送时,都会在窗口字段填入自己的接收窗口值,从而告诉对方最多传送多少数据。

    如下,一开始B的接收窗口为400

    在这里插入图片描述

    随后A连续发送了三个报文,分别是[1, 100][101, 200][201, 300]。而第三个报文丢失了。

    随后B发送了一个确认报文,此时rwnd就是窗口字段的值,表明当前自己的接收窗口是多少Brwnd控制为300并告知A

    在这里插入图片描述

    随后A发送了[301, 400][401, 500]并重传了[201, 300]

    在这里插入图片描述

    此时A计算出到已经发送到对方接收窗口的最大值了,不会再发送数据了。

    直到BA发送新的报文,将rwnd = 100,表示可以再发送100个数据:

    在这里插入图片描述

    最后B又发送一个rwnd = 0的报文,表示接下来A不要发送任何数据了:

    在这里插入图片描述

    通过这样一个控制接收窗口的过程,你会发现A想要发多少数据,都由B来控制了,这就是流量控制


    拥塞控制

    在某段时间内,若对网络中某资源(带宽、缓存、处理机等)的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这种情况称为拥塞 (congestion)。

    拥塞控制就是防止过多的数据注入到网络中,以防网络中的路由器或链路过载。它是一个全局性的过程,涉及到所有的主机和路由器。

    为了进行拥塞控制,发送方维持一个叫做拥塞窗口 cwnd的状态变量。发送窗口的值是拥塞窗口接收窗口的较小值。本博客为了方便理解,假设接收窗口的值一直大于拥塞窗口,也就是说发送窗口的值一直和拥塞窗口保持一致。

    发送方控制拥塞窗口的原则是:

    • 只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,提高网络的利用率。
    • 但只要网络出现拥塞(依据就是出现了超时),拥塞窗口就减小一些,以减少注入到网络中的分组数,缓解网络出现的拥塞。

    TCP进行依赖四种算法:满开始拥塞避免快重传快恢复

    慢开始算法

    慢开始算法的思路是:

    当主机在刚建立的 TCP 连接上发送数据时,并不清楚网络当前的状况,不宜把大量的数据注入网络,而是应当由小到大逐渐增大注入到网络中的数据量,即由小到大逐渐增大拥塞窗口的数值。

    慢开始算法的规则是:

    每收到一个确认报文,就把cwnd的值增大1

    如图所示:

    在这里插入图片描述

    首先明确轮次的概念:发送方把拥塞窗口所允许发送的报文段都连续发送出去,并收到对这些报文段的确认所经历的时间,就叫一个轮次。

    第一轮次cwnd = 1,只能发送一个数据,接收方收到这个数据后回应一个确认报文。发送方接收到一个回应报文,cwnd = cwnd + 1

    第二轮次发送窗口cwnd就变成了2,此时发送方就可以一次发送两个数据报,接收方就回应两个确认报文。发送方接收到两个回应报文,cwnd = cwnd +2

    第三轮次发送窗口cwnd就变成了4,此时发送方就可以一次发送四个数据报,接收方就回应四个确认报文。发送方接收到四个回应报文,cwnd = cwnd +4

    于是发送窗口cwnd变为8,以此类推。

    你会发现:处于慢开始阶段,cwnd呈指数级增长。为了控制拥塞窗口增加过快,此时会设置一个慢开始门限 sstresh

    • cwnd < ssthresh 时,使用慢开始算法。
    • cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
    • cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞避免算法。

    接下来我们就讲解拥塞避免算法。


    拥塞避免算法

    拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢地增大,规则如下:

    每经过一个轮次,把拥塞窗口 cwnd 值加 1

    拥塞避免并非完全避免拥塞,而是让拥塞窗口增长得缓慢些,使网络不容易出现拥塞。

    如图所示:

    在这里插入图片描述

    横坐标为轮次,纵坐标为cwnd值。当cwnd < sstresh时,执行慢开始算法,此时cwnd指数级增长。当cwnd = 16 = sstresh时,改用拥塞避免算法,每个轮次cwnd = cwnd + 1,此时呈现线性增长

    无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,此时就会重新调整cwnd,和sstresh规则如下:

    ssthresh 设置为出现拥塞时的拥塞窗口值的一半。然后把拥塞窗口 cwnd 重新设置为 1,并执行慢开始算法。

    这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间处理队列中积压的分组。

    如图:

    在这里插入图片描述

    等到第13个轮次,此时某个报文超时重传了,于是主机认为此时网络拥塞了,于是sshtresh = cnwd / 2 = 12cwnd = 1,并重新执行慢开始算法。

    随后当慢开始执行到cwnd = 12时,cwnd = sstresh,由执行拥塞避免了。


    慢开始拥塞避免1988年提出的TCP拥塞控制算法,在1990年由增加了两个算法:快重传快恢复算法。

    快重传算法

    为了避免单个报文段的意外丢失被发送方误认为网络产生了拥塞,同时为了让发送方尽早知道有个别报文段没有按序到达接收方,需要应用快重传算法。

    快重传算法首先要求接收方每收到一个失序的报文段就立即发出对已收到的报文段的重复确认。当发送方连续收到三个重复的确认时,就执行快重传,这样就不会出现超时,发送方也就不会误认为网络出现了拥塞。

    如图:

    在这里插入图片描述

    发送方发送M3丢失了,如果按照以前的算法,此时M3超时重传就会把cwnd = 1,就要从头开始增长了,导致传输效率降低。

    于是当接收方收到M4M5M6时,都发送M3的确认报文,此时发送方连续收到三个M2确认报文,立刻重传M3,这个重传不算超时重传,不会触发网络拥塞的判断条件,后续就可以正常传输了。


    快恢复算法

    发送方在收到三个连续确认报文,执行快重传丢失的报文段的同时,执行快恢复算法:

    令拥塞窗口 cwnd 减半,并设置慢开始门限 ssthresh 为同样的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大

    如图:

    在这里插入图片描述

    这是在,没有快恢复快重传的时候,遇到报文丢失后超时重传触发的机制。

    而现在如果报文丢失,执行快恢复快重传,那么整体恢复速度就很快了:

    在这里插入图片描述

    执行快重传的时候,sstresh = cwnd = cwnd / 2 = 12,然后立刻执行拥塞避免,此时就可以在很短的时间内恢复到之前的状态了。


  • 相关阅读:
    机器学习8线性回归法Linear Regression
    开源之夏 2023 | Databend 社区项目总结与分享
    Unity中从3D模型资产中批量提取材质
    hbase和aerospike基础概念及所对应的python包API使用
    安装了 vue-cli,竟然提示 zsh: command not found: v
    Java通用C# SM2加密解密
    Pyramid Scene Parsing Network–CVPR,2017论文解读及其pytorch代码
    什么是代理IP池?真实测评IP代理商的IP池是否真实?
    mysql 自定义函数create function
    spring5.0 源码解析 populateBean 10
  • 原文地址:https://blog.csdn.net/fsdfafsdsd/article/details/139800014