【计算机网络】TCP流量控制和拥塞控制

1、TCP流量控制面试

所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。算法

一、利用滑动窗口实现流量控制缓存

注:每一个报文段为 100 字节长,而数据报文段序号的初始值设置为 1。网络

在箭头上面大写 ACK表示首部中的确认位 ACK,小写 ack 表示字段的值。只有 ACK = 1 时,确认号字段才有意义。spa

从上图,能够看出接收方的主机 B 进行了三次流量控制。第一次把窗口减少到 rwnd = 300,第二次减少到 rwnd = 100,最后减少到 rwnd = 0,即不容许发送方在发送数据了。这种发送方暂停发送将持续到主机 B 从新发出一个新的窗口值为止。blog


二、持续计时器队列

考虑存在一种状况:在图中,B 向 A 发送的带有新的接收窗口值的报文段丢失, A 一直等待 收到 B 的发送的非零窗口的通知,而 B 也一直等待 A 发送的数据。若是没有其余措施,这种相互等待的死锁局面将会一直延续下去。进程

为了解决这个问题,TCP 为每一个链接设有一个持续计时器。路由

(1)只要 TCP 链接的一方收到对方的零窗口通知,就启动持续计时器。it

(2)若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据),而对方就在确认这个探测报文段时给出了如今的窗口值。

(3)若是窗口值仍然为零,那么收到这个报文段的一方就从新设置持续计时器。若是窗口不是零,那么死锁的僵局就能够打破了。

三、必须考虑效率传输

能够用同的机制来控制TCP报文段的发送时机。例如:

(1)第一种机制:TCP维持一个变量,它等于最大报文段长度 MMS。只要缓存中存放的数据达到 MSS 字节时,就组装成一个 TCP 报文段发送出去。

(2)第二种机制:由发送方的应用进程指明要求发送报文段,即 TCP 支持的推送(PUSH)操做。

(3)第三种介质:发送方的一个计时器期限到了。这时就把当前已有的缓存数据装入报文段(但长度不能超过 MSS)发送出去。


Nagle 算法:

若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存,则发送方就把第一个数据字节发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,在把发送缓存中的全部数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减小所用的网络宽带。Nagle 算法还规定,当到达的数据已到达发送窗口大小的一半或已到达报文段的最大长度时,就当即发送一个报文段。这样作,就能够有效的提升网络的吞吐量。

糊涂窗口综合症:

TCP 接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取 1 个字节(这样就使接受缓存空间腾出 1 个字节),而后向发送方确认,并把窗口设置为 1 个字节(但发送的数据报是 40 字节长)。接着发送方又来 1 个字节的数据(请注意,发送方的 IP 数据报是 41 字节长)。接收方发回确认,仍然将窗口设置为  1 个字节。这样进行下去,是网络的效率很低。

要解决这个问题,可让接收方等待一段时间,使得或者接收缓存已有足够的缓存空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种状况之一,接收方就发出确认报文,并向发送发通知当前窗口的大小。此外,发送方也不要发送过小的报文段,而是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小。


2、TCP拥塞控制

拥塞控制和流量控制的关系密切,它们之间也存在这一些差异。所谓拥塞控制就是防止过多的数据注入到网络中这样可使网络中的路由器或链路不致过载。拥塞控制所要作的都有一个前提,就是网络可以承受现有的网络符合。拥塞控制是一个全局性的过程。相反,流量控制每每指点对点通讯量的控制是个端到端的问题(接收端控制发送端)。流量控制所要作的就是抑制发送端发送数据的速率,以便使接收端来得及接收。


拥塞控制方法

一、慢开始和拥塞避免

慢开始的慢并非指 cwnd 的增加速率慢,而是指在 TCP 开始发送报文段时先设置 cwnd = 1 ,使得发送方在开始时只发送一个报文段(目的是先探测一下网络的拥塞状况),而后逐渐增大 cwnd 。这固然比按照大的 cwnd 一会儿把许多报文段忽然注入到网络中去要慢的多。

为了防止拥塞窗口 cwnd 增加过大引发的网络拥塞,还须要设置一个慢开始门限 ssthresh 状态变量。慢开始门限的用法以下:

(1) 当 cwmd < ssthresh 时,使用上述的慢开始算法。

(2)当 cwnd > ssthresh 时,中止使用慢开始算法,而改用拥塞避免算法。

(3)当 cwnd == ssthresh 时,便可使用慢开始算法,也可以使用拥塞避免算法。

拥塞避免算法的思路是:让拥塞窗口 cwnd 缓慢的增大,每通过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1 ,而不是加倍,这样 cwnd 按线性规律缓慢增加,比慢开始算法的拥塞窗口增加速率缓慢的多。

慢开始门限的设定:

不管在慢开始阶段仍是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认),就把慢开始门限 ssthresh 设置为出现拥塞窗时的发送窗口的一半(但不能小于2)。而后把拥塞窗口 cwnd 从新设置为 1,执行慢开始算法。这样作的目的就是要迅速减小主机发送到网络中的分组数,使得发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。

二、快重传和慢恢复

快重传算法首先要求接收方每收到一个失序的报文段后就当即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等待本身发送数据时才进行捎带确认(为的是是发送双方及早知道有报文段没有到达对方)而不要等待本身发送数据时才进行捎带确认。

快重传算法规定:发送方只要一连收到三个重复确认就应当当即重传对方还没有收到的报文段,而没必要继续等待设置的重传计时器到期。

与快重传算法配合使用的还有快恢复算法,其过程有两个要点:

(1)当发送方连续收到三个重复确认时,就执行 “乘法减少” 算法,把慢开始门限减半。这是为了预防网络发生拥塞。注意,接下去不执行慢开始算法。

(2)执行快恢复算法时,把 cwnd 从新设置为慢开始门限 ssthresh 减半后的数值,而后开始执行拥塞避免算法,使得拥塞窗口缓慢性增大。


3、常见面试题:

拥塞避免: 
  让拥塞窗口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