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

一、TCP流量控制

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

1、利用滑动窗口实现流量控制

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

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

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


2、持续计时器

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

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

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

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

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

3、必须考虑效率传输

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

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

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

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


Nagle 算法:

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

糊涂窗口综合症:

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

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


二、TCP拥塞控制

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


拥塞控制方法

1、慢开始和拥塞避免

慢开始的慢并不是指 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,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。

2、快重传和慢恢复

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

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

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

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

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


三、常见面试题:

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


猜你喜欢

转载自blog.csdn.net/qq_35396127/article/details/80019516