北冰洋以北 发表于 2025-4-5 12:53:15

计算机网络-TCP的拥塞控制

内容泉源:小林coding
本文是对小林coding的TPC拥塞控制的精简总结
为什么要有拥塞控制?

前面的流量控制是制止「发送方」的数据填满「接收方」的缓存,但是并不知道网络的中发生了什么
 
计算机网络都处在一个共享的情况,因此也有大概会由于其他主机之间的通讯使得网络拥堵

在网络出现拥堵时,如果继续发送大量数据包,大概会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不停地放大....
 
以是,TCP 不能忽略网络上发生的事,它被筹划成一个无私的协议
当网络发送拥塞时,TCP 会自我牺牲,降低发送的数据量
 
拥塞控制的目的:制止「发送方」的数据填满整个网络
为了在「发送方」调节所要发送数据的量,定义了一个叫做「拥塞窗口」的概念
什么是拥塞窗口?和发送窗口有什么关系呢?

什么是拥塞窗口

拥塞窗口 cwnd 是发送方维护的一个的状态变量
它会根据网络的拥塞程度动态变革的
我们在前面提到过发送窗口 swnd 和接收窗口 rwnd 是约即是的关系,那么由于加入了拥塞窗口的概念后
此时发送窗口的值是 swnd = min (cwnd, rwnd)
也就是拥塞窗口和接收窗口中的最小值
拥塞窗口 cwnd 变革的规则

1.只要网络中没有出现拥塞,cwnd 就会增大
2.但网络中出现了拥塞,cwnd 就淘汰
怎么判断当前网络出现了拥塞

其实只要「发送方」没有在规定时间内接收到 ACK 应答报文
也就是发生了超时重传,就会以为网络出现了拥塞
 

拥塞控制有哪些控制算法 

拥塞控制主要是四个算法:


[*]慢启动
[*]拥塞制止
[*]拥塞发生
[*]快速恢复
慢启动

慢启动是什么意思?

TCP 在刚建立连接完成后,首先是有个慢启动的过程
慢启动的意思:一点一点的提高发送数据包的数目
如果一上来就发大量的数据,这不是给网络添堵吗?
慢启动算法规则

慢启动的算法记住一个规则就行:
当发送方每收到一个 ACK,拥塞窗口 cwnd 的巨细就会加 1
图解例子

这里假定拥塞窗口 cwnd 和发送窗口 swnd 相等,下面举个栗子:


[*]连接建立完成后,一开始初始化 cwnd = 1,表示可以传一个 MSS 巨细的数据。
[*]当收到一个 ACK 确认应答后,cwnd 增加 1,于是一次能够发送 2 个。
[*]当收到 2 个的 ACK 确认应答后,cwnd 增加 2,于是就可以比之前多发 2 个,以是这一次能够发送 4 个。
[*]当这 4 个的 ACK 确认到来的时间,每个确认 cwnd 增加 1,4 个确认 cwnd 增加 4,于是就可以比之前多发 4 个,以是这一次能够发送 8 个。
慢启动算法的变革过程如下图:
 
https://i-blog.csdnimg.cn/img_convert/507fab086086e127b1de8004039a93fa.png
可以看出慢启动算法,发包的个数是指数性的增长
慢启动门限(我们慢启动增长到啥时间停止?)

有一个叫慢启动门限 ssthresh(slow start threshold)状态变量。


[*]当 cwnd < ssthresh 时,利用慢启动算法。
[*]当 cwnd >= ssthresh 时,就会利用「拥塞制止算法」
拥塞制止算法

怎么进入进入拥塞制止算法

前面说道,当拥塞窗口 cwnd「超过」慢启动门限 ssthresh 就会进入拥塞制止算法
一样平常来说 ssthresh 的巨细是 65535 字节
拥塞制止算法规则

那么进入拥塞制止算法后,它的规则是:每当收到一个 ACK 时,cwnd 增加 1/cwnd
图解例子

接上前面的慢启动的栗子,现假定 ssthresh 为 8:


[*]当 8 个 ACK 应答确认到来时,每个确认增加 1/8,8 个 ACK 确认 cwnd 一共增加 1,于是这一次能够发送 9 个 MSS 巨细的数据,变成了线性增长。
拥塞制止算法的变革过程如下图:
 
https://i-blog.csdnimg.cn/img_convert/3921715969d8d8cc5627f39656a9e97c.png
以是,我们可以发现,拥塞制止算法就是将原本慢启动算法的指数增长变成了线性增长,还是增长阶段,但是增长速度迟钝了一些
就这么一直增长着后,网络就会慢慢进入了拥塞的状况了,于是就会出现丢包征象,这时就须要对丢失的数据包进行重传。
当触发了重传机制,也就进入了「拥塞发生算法」
拥塞发生算法

数据包重传的两种机制

当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:


[*]超时重传
[*]快速重传
 

【超时重传】的拥塞发生算法规则

当发生了「超时重传」,则就会利用拥塞发生算法
这个时间,ssthresh 和 cwnd 的值会发生变革:


[*]ssthresh 设为 cwnd/2,
[*]cwnd 重置为 1(是恢复为 cwnd 初始化值,我这里假定 cwnd 初始化值 1)
怎么查看系统的cwnd初始值

Linux 针对每一个 TCP 连接的 cwnd 初始化值是 10,也就是 10 个 MSS
我们可以用 ss -nli 命令查看每一个 TCP 连接的 cwnd 初始化值
如下图
 
https://i-blog.csdnimg.cn/img_convert/fc025976ec4b7c50de660655e108ee03.png
图解

 
https://i-blog.csdnimg.cn/img_convert/f254569367f132b618f6a70197fa21a5.png
接着,就重新开始慢启动,慢启动是会突然淘汰数据流的
这真是一旦「超时重传」,马上回到解放前。但是这种方式太激进了,反应也很强烈,会造成网络卡顿。
就似乎本来在秋名山高速漂移着,突然来个告急刹车,轮胎受得了吗。。。
【快速重传】的拥塞发生算法

另有更好的方式,前面我们讲过「快速重传算法」
当接收方发现丢了一个中间包的时间,发送三次前一个包的 ACK,于是发送端就会快速地重传,不必等待超时再重传。
TCP 以为这种情况不严重,由于大部门没丢,只丢了一小部门,则 ssthresh 和 cwnd 变革如下:


[*]cwnd = cwnd/2,也就是设置为原来的一半;
[*]ssthresh = cwnd;
[*]进入快速恢复算法
快速恢复

快速恢复算法规则
快速重传和快速恢复算法一样平常同时利用
快速恢复算法是以为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕
以是没有须要像 RTO 超时时那么强烈
正如前面所说,进入快速恢复之前,cwnd 和 ssthresh 已被更新了:


[*]cwnd = cwnd/2,也就是设置为原来的一半;
[*]ssthresh = cwnd;
快速恢复算法规则

然后,进入快速恢复算法如下:


[*]拥塞窗口 cwnd = ssthresh + 3 (3 的意思是确认有 3 个数据包被收到了);
[*]重传丢失的数据包;
[*]如果再收到重复的 ACK,那么 cwnd 增加 1;
[*]如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,缘故原由是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞制止状态;
图解

也就是没有像「超时重传」一夜回到解放前,而是还在比力高的值,后续呈线性增长
 

https://i-blog.csdnimg.cn/img_convert/e98c67cf064aade7b25975c71c50f4c9.png
 
简单总结一下拥塞控制

为什么要有拥塞控制

流量控制是制止「发送方」的数据填满「接收方」的缓存,但是并不知道网络的中发生了什么

在网络出现拥堵时,如果继续发送大量数据包,大概会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不停地放大....
 
当网络发送拥塞时,TCP 会自我牺牲,降低发送的数据量
 
拥塞控制的目的:制止「发送方」的数据填满整个网络
什么是拥塞窗口

拥塞窗口 cwnd 是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变革的
发送窗口 swnd
接收窗口 rwnd
这两个窗口是约即是的关系
发送窗口的值是拥塞窗口和接收窗口中的最小值, swnd = min (cwnd, rwnd)
 
拥塞窗口 cwnd 变革的规则

1.只要网络中没有出现拥塞,cwnd 就会增大
2.但网络中出现了拥塞,cwnd 就淘汰
 
怎么判断当前网络出现了拥塞

「发送方」没有在规定时间内接收到 ACK 应答报文
也就是发生了超时重传,就会以为网络出现了拥塞
 
拥塞控制有哪些算法

拥塞控制主要是四个算法:


[*]慢启动
[*]拥塞制止
[*]拥塞发生
[*]快速恢复
慢启动

什么是慢启动

CP 在刚建立连接完成后,首先是有个慢启动的过程
慢启动的意思:一点一点的提高发送数据包的数目
如果一上来就发大量的数据,这不是给网络添堵吗?
慢启动规则

发送方每收到一个 ACK,拥塞窗口 cwnd 的巨细就会加 1
慢启动门限

慢启动门限 :ssthresh(slow start threshold)状态变量


[*]当 cwnd < ssthresh 时(拥塞窗口小于慢启动门限时),利用慢启动算法
[*]当 cwnd >= ssthresh 时(拥塞窗口大于即是慢启动门限时),就会利用「拥塞制止算法」
拥塞制止

如何进入拥塞制止

当拥塞窗口 cwnd「超过」慢启动门限 ssthresh 就会进入拥塞制止算法
 
拥塞制止规则

每当收到一个 ACK 时,cwnd 增加 1/cwnd
拥塞制止算法就是将原本慢启动算法的指数增长变成了线性增长,还是增长阶段,但是增长速度迟钝了一些
 
重传机制的拥塞发生规则

数据包的两种重传机制



[*]超时重传
[*]快速重传
【超时重传】的拥塞发生算法规则

「超时重传」会利用拥塞发生算法
ssthresh(慢启动门限) 和 cwnd(拥塞窗口) 的值会发生变革:


[*]慢启动门限=拥塞窗口/2
[*]拥塞窗口重置为 1(是恢复为 cwnd 初始化值,我这里假定 cwnd 初始化值 1)
如何查看TPC连接的CWND初始化值

ss -nli 【快速重传】的拥塞发生算法规则

之前的「快速重传算法」
当接收方发现丢了一个中间包的时间,发送三次前一个包的 ACK,于是发送端就会快速地重传,不必等待超时再重传
TCP 以为这种情况不严重,由于大部门没丢,只丢了一小部门,则 ssthresh 和 cwnd 变革如下:


[*]拥塞窗口变为原来的一半;
[*]慢启动门限=拥塞窗口;
[*]进入快速恢复算法
快速恢复

为什么须要快速恢复

慢启动是会突然淘汰数据流的
这真是一旦「超时重传」,马上回到解放前。但是这种方式太激进了,反应也很强烈,会造成网络卡顿
什么是快速恢复

快速重传和快速恢复算法一样平常同时利用
快速恢复算法是以为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕
以是没有须要像 RTO 超时时那么强烈
快速恢复算法规则

快速恢复的前提步骤:
ssthresh(慢启动门限) 和 cwnd(拥塞窗口) 的值会发生变革:


[*]ssthresh 慢启动门限=拥塞窗口/2
[*]cwmd 拥塞窗口重置为 1(是恢复为 cwnd 初始化值,我这里假定 cwnd 初始化值 1)
 
快速恢复算法


[*]拥塞窗口 cwnd = ssthresh + 3 (3 的意思是确认有 3 个数据包被收到了);
[*]重传丢失的数据包;
[*]如果再收到重复的 ACK,那么 cwnd 增加 1;
[*]如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,缘故原由是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞制止状态;
图解总结

 
https://i-blog.csdnimg.cn/img_convert/1a4e5c3e635ceebdcc23ea877d55e92b.png
 
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 计算机网络-TCP的拥塞控制