前言
一般情况下,网络丢包是因为当前网络变得拥塞时由于路由器缓存溢出引起的,在实践中有两种主要拥塞控制方法,分别是端到端拥塞控制和网络辅助的拥塞控制
端到端拥塞控制
- 端到端拥塞控制
- 网络层没有为运输层拥塞控制提供显示支持,端系统也必须通过对网络行为的观察(例如分组丢失与时延)来推断是否拥塞
- 通常,丢包事件定义为:要么出现超时,要么收到来自接收方的3个冗余ACK
- 网络辅助的拥塞控制
- 路由器向发送方提供关于网络中拥塞状态的显示反馈信息
- 路由器标记或更新从发送方流向接收方的分组中的某个字段来指示拥塞的产生
TCP必须使用端到端拥塞控制而不是使用网络辅助的拥塞控制,是因为IP层不向端系统提供显示的网络拥塞反馈
TCP采用的方法是让每一个发送方根据所感知到的网络拥塞控制来限制其能向连接发送流量的速率
TCP拥塞控制算法
该算法主要包括三个部分,分别是慢启动、拥塞避免和快速恢复
其中慢启动和拥塞避免的差异在于对收到的ACK作出反应时增加cwnd长度的方式,是强制的,快速恢复是推荐的,并非必需的
发送方会维护一个拥塞窗口,表示为cwnd,它对一个TCP发送方能向网络中发送流量的速率进行了限制
在TCP双方建立连接后,拥塞窗口cwnd设置为1个MSS(MSS:最大报文长度),还需要设置一个慢启动阀值ssthresh = cwnd/2
- 当 cwnd < ssthresh 时,使用慢启动算法
- 当 cwnd > ssthresh 时,停止使用慢启动算法而改用拥塞避免算法
- 当 cwnd = ssthresh 时,既可使用慢启动算法,也可使用拥塞避免算法
1. 慢启动
cwnd的值以1个MSS开始并且每当传输的报文段首次被确认就增加1个MSS
如图,一开始是1个报文段,接收到确认后就增加1个MSS,发送2个最大长度的报文段,被确认后又增加1个MSS,发送4个最大长度的报文段(也就是 1、2、4、8...这样的增长,指数增长)
那么何时结束慢启动呢?有以下三种方式
- 如果存在一个由超时指示的丢包事件(其实就是拥塞啦!),TCP发送方将cwnd设置为1并重新开始慢启动
- 如果检测到cwnd到达或超过ssthresh时,结束慢启动并转移到拥塞避免模式
- 如果检测到3个冗余ACK,就执行快速重传并进入快速恢复状态
以上就是慢启动的全部内容
那么什么是拥塞避免呢?继续往下看~
2. 拥塞避免
我们是在cwnd超过ssthresh的时候转为拥塞避免的状态,因为如果在cwnd已经达到或者超过ssthresh时还继续以慢启动的指数增长方式,有些鲁莽,因此我们选择更为保守的方式——每个RTT只将cwnd的值线性增加
例如,假设MSS=1460字节,cwnd=14600字节
那么在一个RTT内发送10个报文段,每个到达ACK就增加 1/10 * MSS 的拥塞窗口长度
当收到所有10个报文段的ACK后,拥塞窗口的值就增加了1个MSS
3. 快速恢复(与快速重传配合使用)
在收到3个重复的ACK后,就知道下一个报文段丢失了,此时执行快速重传,即立刻重传下一个报文
但是这种情况只是丢失了个别报文段,而不是网络拥塞
此时执行快速恢复,令ssthresh = cwnd/2,cwnd=ssthresh,直接进入拥塞避免。
流量控制和拥塞控制的区别
-
拥塞控制是防止过多的数据注入到网络中,可以使网络中的路由器或链路不致过载,是一个全局性的过程
-
流量控制是点对点通信量的控制,是一个端到端的问题,主要就是抑制发送端发送数据的速率,以便接收端来得及接收