在网络实际的传输过程中,会出现拥塞的现象,网络上充斥着非常多的数据包,但是却不能按时被传送,形成网络拥塞,其实就是和平时的堵车一个性质了。TCP设计中也考虑到这一点,使用了一些算法来检测网络拥塞现象,如果拥塞产生,就会调整发送策略,减少数据包的发送来缓解网络的压力
解决方法:
-
慢启动
-
拥塞避免
-
拥塞发生时,快速重传
-
快速恢复
慢启动
之前介绍的滑动窗口能够让协议栈同时发送多个报文段,这样可以提高网络通信的效率,对于一些处理能力不佳的中间路由器,很可能会导致存储被耗尽的状况,从而严重降低了TCP连接的吞吐量,不断的重传. 非常的可怕, 介于此,引入了慢启动这个算法。
慢启动为发送方的TCP增加了一个窗口:拥塞窗口,记为cwnd,,初始化之后慢慢增加这个cwnd的值来提升速度。同时也引入了ssthresh门限值,如果cwnd达到这个值会让cwnd的增长变得平滑,算法如下
-
连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据
-
每当收到一个ACK,cwnd++; 呈线性上升
-
每当过了一个RTT(从发送端发送数据开始,到发送端收到来自接收端的确认),cwnd = cwnd*2; 呈指数让升
-
当cwnd >= ssthresh时,就会进入“拥塞避免算法”
注意:真正发送窗口大小是 拥塞窗口 和 接收端发过来的窗口取较小值
拥塞避免算法
从慢启动可以看到,cwnd可以比较快的增长,但是不能一直无限增长,需要某个限制,TCP使用了ssthresh的变量,当cwnd超过这个值后,慢启动过程结束,进入拥塞避免阶段。拥塞避免的主要思想是加法增大,也就是让cwnd的值线性增加, 此时当窗口中所有的报文段都被确认是,cwnd的大小才加1,cwnd的值随着RTT线性增加,这样就可以避免增长过快导致网络拥塞,慢慢的增加到网络的最佳值。
算法:
1)收到一个ACK时,cwnd = cwnd + 1/cwnd
2)当每过一个RTT时,cwnd = cwnd + 1