TCP的可靠传输、拥塞控制和流量控制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_34715587/article/details/88874085

一、可靠传输

  • 对于收到的请求,给出确认响应
  • 超时重传

二、拥塞控制

  1. 前提:网络能够承受现有的网络负荷。
  2. 拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
  3. 与流量控制的区别:流量控制往往是指点对点通信量的控制,是个端到端的问题。流量控制所要做的就是控制发送端发送数据的速率,以便使接收端来得及接收。
  4. 代价:需要获得网络内部流量分布的信息。在实施拥塞控制之前,还需要在结点之间交换信息和各种命令,以便选择控制的策略和实施控制。这样就产生了额外的开销。拥塞控制还需要将一些资源分配给各个用户单独使用,使得网络资源能更好的实现共享。

拥塞控制产生原因:∑对资源的需求>可用资源

在某段时间,如果对网络中的某一资源(比如链路容量,交换节点中的缓存和处理机等)的需求超过了该资源所能提供的可用部分,网络的性能就要发生变化,这种情况叫拥塞

拥塞控制,是防止过多的数据注入到网络当中,这样可以使网络中的路由器或链路不致过载。(通过拥塞窗口处理网络拥塞现象的一种机制)。

拥塞窗口:发送方维持一个拥塞窗口 cwnd ( congestion window )的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞。

拥塞控制的作用

吞吐量代表一定时间内从网络中传输的分组量。在吞吐量饱和之前负载和吞吐量应该相等,也就是直线的斜度45°,直到网络资源受限,吞吐量饱和。当提供的负载继续增大到某一数值时,网络的吞吐量就下降到零,网络无法工作,产生所谓的死锁。

注意 
单纯的增加网络资源无法解决问题。
例如:把结点的存储空间扩大,更换更高速率的链路,提高结点处理机的运算速度,不仅不能解决问题,而且可能使网络性能更坏。 
原因:网络拥塞是许多因素引起的,单纯的解决一个可能会使上述情况得到一些缓解,但是会把拥塞转移到其他地方。 
扩大结点存储空间——>由于输出链路的容量和处理机的速度并未提高,增大排队等待时间,超时重传,浪费资源。 
更换更高速率的链路——>可能会缓解,有可能造成各部分不匹配。

拥塞的标志

  • 重传计时器超时 
  • 接收到三个重复确认

拥塞控制的机制

拥塞控制可以分为开环控制和闭环控制

  • 开环控制,在设计网络时把因素考虑到;
  • 闭环控制,基于反馈环路,使用拥塞的信息来进行调整网络。

拥塞控制的几种方法慢开始拥塞避免快重传快恢复

  • 慢开始的“慢”并不是指增长速率的慢,而是指在TCP开始发送报文段时先设置拥塞窗口为1。
  • 拥塞避免:使拥塞窗口按线性规律增长。
  • 快重传:发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待为其设置的重传计时器到期。
  • 快恢复(与快重传配合使用):当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把慢开始门限减半。这是为了预防网络发生拥塞。请注意,接下来不执行慢开始算法。由于发送方现在认为网络很可能没有发生拥塞(如果网路发生了严重的拥塞,就不会一连有好几个报文段连续达到接收方,就不会导致接收方连续发送重复确认),因此与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口现在不设置为1),而是把它设置为慢开始门限减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增长。

拥塞控制几种方法(详解)

  • 慢开始

a.算法原理:当主机开始发送数据时,如果立即将大量数据字节注入到网络,那么就有可能因为不清楚当前网络的负荷情况而引起网络阻塞。所以,最好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。通常在刚刚发送报文段时,先把拥塞窗口cwnd设置为一个最大报文段MSS的数值。而在每收到一个新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。(慢开始当中的“慢”并不是指cwnd的增长速率慢,而是在TCP开始发送报文段时先设置cwnd = 1,使得发送方在开始时只发送一个报文段)。

不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。这里用报文段的个数的拥塞窗口大小举例说明慢开始算法,实时拥塞窗口大小是以字节为单位的。如下图。

当rwnd足够大的时候,为了防止拥塞窗口cwnd的增长引起网络阻塞,还需要另外一个变量------慢开始门限ssthresh

    i.当cwnd < ssthresh时,使用上述慢启动算法;

    ii.当cwnd >ssthresh时,停止使用慢启动算法,改用拥塞避免算法;

    iii.当cwnd = ssthresh时,两者皆可。

b.慢开始的局限性

    i.需要获得网络内部流量分布的信息,浪费可用的网络容量,额外开销;

    ii.估算合理的ssthresh值并不容易,可能耗时较长; 

注:

i.接收端窗口rwnd,又称通知窗口(awnd),是接收端根据目前的接收缓存大小所许诺的最新窗口值,是来自接收端的流量控制。

ii.拥塞窗口cwnd是发送端根据自己估计的网络阻塞程度而设置的窗口值,是来自发送端的流量控制。

iii.MSS是TCP数据包每次能够传输的最大数据分段,其中并不包括TCP首部。而MSS只出现在syn报文段当中。一般来说MSS的值在不分段的情况下越大越好(eg.一个外出接口的MSS值是MTU减去IP和TCP首部长度)
 

  • 拥塞避免

a.算法思路:拥塞避免并非完全能够避免拥塞,是说在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。 让拥塞窗口cwnd缓慢的增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口cwnd按线性规律缓慢的增长,比慢开始算法的拥塞窗口增长速率缓慢的多。

无论是慢启动算法还是拥塞避免算法,只要判断网络出现拥塞(其根据就是没有收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就要把慢开始门限(ssthresh)设置为发送窗口的一半(>=2),拥塞窗口cwnd设置为1,然后再使用慢启动算法,这样做的目的能迅速的减少网络当中的数据传输,使发生拥塞的路由器能够把队列中堆积的分组处理完毕。拥塞窗口是按照线性的规律增长。 

b.控制过程

  1. TCP连接初始化,将拥塞窗口cwnd设置为1个报文段,即cwnd = 1;
  2. 执行慢开始算法,cwnd按指数规律增长,知道cwnd == ssthresh时,开始执行拥塞避免算法,cwnd开始按照线性规律增长;
  3. 当网络发生拥塞,把ssthresh值更新为拥塞前ssthresh值的一半,cwnd重新设置为1,再按照2执行;

例如:

a.在TCP连接进行初始化的时候,cwnd = 1,ssthresh = 16;

b.在慢启动算法开始时,cwnd的初始值是1,每次发送方收到一个ACK拥塞窗口就增加1,当ssthresh == cwnd时,启动拥塞控制算法,拥塞窗口按照线性规律增长;

c.当cwnd = 24时,网络出现超时,发送方收不到确认ACK,此时设置ssthresh = 12,设置cwnd = 1,然后开始慢启动算法,当cwnd = ssthresh=12,慢启动算法变为拥塞控制算法,cwnd按照线性速度增长。

AIMD算法(加法增大乘法减小)

a.乘法减小:无论在慢启动阶段还是在拥塞控制阶段,只要网络出现超时,就是将cwnd置为1,sthresh置为cwnd的一半,然后开始执行慢启动算法;

b.加法增大:当网络频繁出现超时情况时,ssthresh就下降的很快,为了减少注入到网络当中的分组数,而加法增大是执行拥塞避免算法后,是拥塞窗口缓慢的增大,以防止网络过早出现拥塞。

这两个结合起来就是AIMD算法,是使用最广泛的算法。拥塞避免算法不能够完全避免网络拥塞,通过控制拥塞窗口的大小只能使网络不易出现拥塞。

  • 快重传

一条TCP连接有时会因为等待重传计时的超时而空闲较长时间,慢开始和拥塞避免无法解决这类问题,因此提出了快重传和快恢复的拥塞控制方法。

a.算法过程:

快重传算法要求首先接收方收到一个失序的报文段后立刻发出重复确认,而不要等待自己发送数据时才进行捎带确认,如下图

在上图中,接收方成功的接受了发送方发来的M1,M2并且分别发送了ACK,现在接收方没有收到M3,而收到了M4,显然接收方不能确认M4,因为M4是失序的报文段。如果根据可靠性传输原理接收方什么都不做,但是按照快速重传算法,在收到M4,M5等报文段的时候,不断重复的向发送方发送M2的ACK,如果接收方一连收到三个重复的ACK,那么发送方不必等待重传计时器到期,由于发送方尽早重传未被确认的报文段。

  • 快恢复

i.当发送方连续收到三个重复确认时,执行“乘法减小”算法,慢启动门限减半,为了预防网络发生阻塞。

ii.由于发送方现在认为网络很可能没有发生阻塞,因此现在不执行慢启动算法,而是把cwnd值设置为慢启动门限减半后的值,然后开始执行拥塞避免算法,拥塞窗口cwnd值线性增大。

注意 

发送方窗口的上限值=Min(接受窗口rwnd,拥塞窗口cwnd) 

rwnd>cwnd 接收方的接收能力限制发送方窗口的最大值 

rwnd<cwnd 网络的拥塞限制发送方窗口的最大值

三、流量控制

所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。利用滑动窗口实现流量控制。

什么是流量控制

Sender won’t overflow receiver’s buffer by transmitting too much, too fast. (防止发送方发的太快,耗尽接收方的资源,从而使接收方来不及处理)

流量控制的一些知识点

  1. 接收端抑制发送端的依据:接收端缓冲区的大小 
  2. 流量控制的目标是接收端,是怕接收端来不及处理 
  3. 流量控制的机制是丢包

怎样实现流量控制

使用滑动窗口

滑动窗口
1.滑动窗口是什么?
滑动窗口是类似于一个窗口一样的东西,是用来告诉发送端可以发送数据的大小或者说是窗口标记了接收端缓冲区的大小,这样就可以实现 
ps:窗口指的是一次批量的发送多少数据

2.为什么会出现滑动窗口?
在确认应答策略中,对每一个发送的数据段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段,这样做有一个比较大的缺点,就是性能比较差,尤其是数据往返的时间长的时候

使用滑动窗口,就可以一次发送多条数据,从而就提高了性能

3.滑动窗口的一些知识点
(1)接收端将自己可以接收的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK来通知发送端 
(2)窗口大小字段越大,说明网络的吞吐率越高 
(3)窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,即就是说不需要接收端的应答,可以一次连续的发送数据 
(4)操作系统内核为了维护滑动窗口,需要开辟发送缓冲区,来记录当前还有那些数据没有应答,只有确认应答过的数据,才能从缓冲区删掉

ps:发送缓冲区如果太大,就会有空间开销

(5)接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端,发送端收到这个值后,就会减慢自己的发送速度 
(6)如果接收端发现自己的缓冲区满了,就会将窗口的大小设置为0,此时发送端将不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端 
ps:在TCP的首部中,有一个16为窗口字段,此字段就是用来存放窗口大小信息的

4.滑动窗口的优点

可以高效可靠的发送大量的数据

流量控制和拥塞控制的区别
1.相同点
(1)现象都是丢包; 
(2)实现机制都是让发送方发的慢一点,发的少一点

2.不同点
(1)丢包位置不同 
流量控制丢包位置是在接收端上 
拥塞控制丢包位置是在路由器上 
(2)作用的对象不同 
流量控制的对象是接收方,怕发送方发的太快,使得接收方来不及处理 
拥塞控制的对象是网络,怕发送发发的太快,造成网络拥塞,使得网络来不及处理

3.联系
拥塞控制
     拥塞控制通常表示的是一个全局性的过程,它会涉及到网络中所有的主机、
     所有的路由器和降低网络传输性能的所有因素
流量控制
     流量控制发生在发送端和接收端之间,只是点到点之间的控制

拥塞控制和流量控制的区别: 

  • 拥塞控制是一个全局性的过程,涉及所有主机和路由器,以及其他因素。 
  • 流量控制是端到端的,发送端和接收端,需要做的是抑制发送端的发送速率,以便来的及接收。

拥塞控制往往是一种全局的,防止过多的数据注入到网络之中,而TCP连接的端点只要不能收到对方的确认信息,猜想在网络中发生了拥塞,但并不知道发生在何处,因此,流量控制往往指点对点通信量的控制,是端到端的问题。

今日头条面试

拥塞避免: 
  让拥塞窗口cwind缓慢地增大,每经过一个往返时间RTT就把发送方的拥塞窗口cwind加1,而不是加倍。这样拥塞窗口cwind线性缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。 
  无论慢启动开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢启动门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwind重新设置为1,执行慢启动算法。目的是迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。

控制过程: 

  -[1]. TCP连接初始化,将拥塞窗口cwind设置为1个报文段,即cwind=1; 
  -[2]. 执行慢开始算法,cwind按指数规律增长,直到cwind == ssthresh时,开始执行拥塞避免算法,cwind按线性规律增长; 
  -[3]. 当网络发生拥塞,把ssthresh值更新为拥塞前ssthresh值的一半,cwind重新设置为1,再按照 [2] 执行。

流量控制:

如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失。

TCP的流量控制是利用滑动窗口机制实现的,接收方在返回的ACK中会包含自己的接收窗口的大小,以控制发送方的数据发送。

但是当某个ACK报文丢失了,就会出现A等待B确认,并且B等待A发送数据的死锁状态。为了解决这种问题,TCP引入了持续计时器(Persistence timer),当A收到rwnd=0时,就启用该计时器,时间到了则发送一个1字节的探测报文,询问B是很忙还是上个ACK丢失了,然后B回应自身的接收窗口大小,返回仍为0(A重设持续计时器继续等待)或者会重发rwnd=x。
 

腾讯面试题 
TCP的拥塞控制机制是什么?请简单说说。 
答:我们知道TCP通过一个定时器(timer)采样了RTT并计算RTO,但是,如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,然而重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这就导致了恶性循环,最终形成“网络风暴” —— TCP的拥塞控制机制就是用于应对这种情况。 
首先需要了解一个概念,为了在发送端调节所要发送的数据量,定义了一个“拥塞窗口”(Congestion Window),在发送数据时,将拥塞窗口的大小与接收端ack的窗口大小做比较,取较小者作为发送数据量的上限。 
拥塞控制主要是四个算法: 
1.慢启动:意思是刚刚加入网络的连接,一点一点地提速,不要一上来就把路占满。 
连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据。 
每当收到一个ACK,cwnd++; 呈线性上升 
每当过了一个RTT,cwnd = cwnd*2; 呈指数让升 
阈值ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法” 
2.拥塞避免:当拥塞窗口 cwnd 达到一个阈值时,窗口大小不再呈指数上升,而是以线性上升,避免增长过快导致网络拥塞。 
每当收到一个ACK,cwnd = cwnd + 1/cwnd 
每当过了一个RTT,cwnd = cwnd + 1 
拥塞发生:当发生丢包进行数据包重传时,表示网络已经拥塞。分两种情况进行处理: 
等到RTO超时,重传数据包 
sshthresh = cwnd /2 
cwnd 重置为 1 
3.进入慢启动过程 
在收到3个duplicate ACK时就开启重传,而不用等到RTO超时 
sshthresh = cwnd = cwnd /2 
进入快速恢复算法——Fast Recovery 
4.快速恢复:至少收到了3个Duplicated Acks,说明网络也不那么糟糕,可以快速恢复。 
cwnd = sshthresh + 3 * MSS (3的意思是确认有3个数据包被收到了) 
重传Duplicated ACKs指定的数据包 
如果再收到 duplicated Acks,那么cwnd = cwnd +1 
如果收到了新的Ack,那么,cwnd = sshthresh ,然后就进入了拥塞避免的算法了。

猜你喜欢

转载自blog.csdn.net/sinat_34715587/article/details/88874085