流量控制和拥塞控制

流量控制和拥塞控制

流量控制和拥塞控制是有区别的。

  • 流量控制:控制双方的传送速率在双方可以接受的范围内。

  • 拥塞控制:描述的是整个网络的状态,通过是否重传以及传输速率的大小去感知网络的拥塞情况,进而进行调整,达到恢复网络的目的。(感知整体网络,通过控制每一个个体去fix网络状况)。

流量控制

流量控制是通过滑动窗口来实现的。滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。

  • ACK: ack是对之前已经收到的数据进行确认。 ack n 表示收到了 n - 1个字节,期待下一个收到从n开始的字节。

  • 重点:发送方根据收到ACK当中的期望收到的下一个字节的序号n以及窗口m,还有当前已经发送的字节序号x,算出还可以发送的字节数。

例子

流量控制和拥塞控制

如图,当收到了ACK 36.表示35以及之前的字节都已经收到了。窗口向右侧移动。

滑动窗口分为两类:

  • 接收窗口

  • 发送窗口

窗口值的设置

流量控制和拥塞控制
TCP的Window是一个16bit位字段,它代表的是窗口的字节容量,也就是TCP的标准窗口最大为2^16-1=65535个字节。 TCP的选项字段中还包含了一个TCP窗口扩大因子,option-kind为3,option-length为3个字节,option-data取值范围0-14。窗口扩大因子用来扩大TCP窗口,可把原来16bit的窗口,扩大为31bit。 一些特殊场景把窗口设置的更大可以加快传输效率。

滑动窗口原理

流量控制和拥塞控制
滑动窗口分为以下几类:

  • 已经发送并得到对端ACK的

  • 已经发送但还未收到对端ACK的

  • 未发送但对端允许发送的

  • 未发送且对端不允许发送

其中中间两部分称之为发送窗口

对应的接收接收端也有相应的窗口分类

  • Received and ACK Not Send to Process:这部分数据属于接收了数据但是还没有被上层的应用程序接收,也是被缓存在窗口内

  •  Received  Not ACK: 已经接收并,但是还没有回复ACK,这些包可能输属于Delay ACK的范畴了

  • Not Received:有空位,还没有被接收的数据。

整体流程

流量控制和拥塞控制

当接收端的处理速度没有发送端的发送速度快时就会导致发送窗口减小为0的情况。例子如下:流量控制和拥塞控制

  1. 包175,发送ACK携带WIN = 384,告知客户端,现在只能接收384个字节

  2. 包176,客户端果真只发送了384个字节。标题为TCP Window Full

  3. 包177,服务器回复一个ACK,并通告窗口为0,说明接收方已经收到所有数据,并保存到缓冲区,但是这个时候应用程序并没有接收这些数据,导致缓冲区没有更多的空间,故通告窗口为0, 这也就是所谓的零窗口,零窗口期间,发送方停止发送数据

  4. 客户端察觉到窗口为0,则不再发送数据给接收方

  5.  包178,接收方发送一个窗口通告,告知发送方已经有接收数据的能力了,可以发送数据包了

  6. 包179,收到窗口通告之后,就发送缓冲区内的数据了.

模糊窗口综合征

简单的说就是有效负荷太小。

当发送端应用进程产生数据很慢、或接收端应用进程处理接收缓冲区数据很慢,或二者兼而有之;就会使应用进程间传送的报文段很小,特别是有效载荷很小。 极端情况下,有效载荷可能只有1个字节;而传输开销有40字节(20字节的IP头+20字节的TCP头) 这种现象就叫糊涂窗口综合症。

这个现象两端都有可能发生。发送端一个字节一个字节发送。(Tlenet发送数据)或者是接收端每次从TCP缓冲copy一个字节进行处理,这个时候通知发送发窗口大小为1,也为导致其发送数据包。

解决方法 - nagle算法

  1. 如果包长度达到MSS,则允许发送;

  2. 如果该包含有FIN,则允许发送;

  3. 设置了TCP_NODELAY选项(意在禁止nagle),则允许发送;

  4. 未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;

  5. 上述条件都未满足,但发生了超时(一般设置延迟ACK,一般为200ms),则立即发送。

   通常我们比较关注的是情况(1)和(5)。

拥塞控制

拥塞控制是对网络整体的检测。防止过多的数据同时堆积在网络中,这样大家都无法传输数据。

拥塞控制的方法主要有:慢开始( slow-start )、拥塞避免( congestion avoidance )、快重传( fast retransmit )和快恢复( fast recovery )。

关键概念

  • 拥塞窗口 cwnd ( congestion window )

  • ssthresh 门限值

拥塞控制就是在对比拥塞窗口,门限,以及不同是时期去做不同的处理。

慢启动

顾名思义,慢启动也就是初始的时候小步开始。探测网络情况。

流量控制和拥塞控制
在刚刚开始发送报文段时,先把拥塞窗口 cwnd 设置为一个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。

慢开始的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,使得发送方在开始时只发送一个报文段(目的是试探一下网络的拥塞情况),然后再逐渐增大cwnd 为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量(如何设置ssthresh)。

慢开始门限ssthresh的用法如下:

  • 当 cwnd < ssthresh 时,使用上述的慢开始算法

  • 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法

  • 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法

拥塞避免

流量控制和拥塞控制
拥塞避免中,让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。

这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多 无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认)。

出现拥塞的时候,修改sshthresh以及cwnd的值。

  • 就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。

  • 然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。

快重传和快恢复

快重传要求接收方在收到了一个失序的报文就发送重复确认。(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。

流量控制和拥塞控制
快恢复算法:

  • 当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半。但是接下去并不执行慢开始算法。

  • 考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。

流量控制和拥塞控制


这里判断应该用的是快恢复还是相应的拥塞避免。

  • ack能够连续收到3次说明网络还有一定的传输能力。

  • 当检测到超时的时候采用拥塞避免。

参考:

https://zhangbinalan.gitbooks.io/protocol/content/tcpde_yong_sai_kong_zhi.html

https://blog.csdn.net/sicofield/article/details/9708383