1、TCP滑动窗口
TCP的滑动窗口主要有两个作用,一是提供TCP的可靠性,二是提供TCP的流控特性。同时滑动窗口机制还体现了TCP面向字节流的设计思路。
TCP 段中窗口的相关字段:
TCP的Window是一个16bit位字段,它代表的是窗口的字节容量,也就是TCP的标准窗口最大为2^16-1=65535个字节。
滑动窗口示意图:
(图片来源)
上图中分成了四个部分,分别是:(其中那个黑模型就是滑动窗口)
- #1已收到ack确认的数据。
- #2发还没收到ack的。
- #3在窗口中还没有发出的(接收方还有空间)。
- #4窗口以外的数据(接收方没空间)
下面是个滑动后的示意图(收到36的ack,并发出了46-51的字节):
窗口的滑动主要包括:
- 窗口左边沿向右边沿靠近,称为窗口合拢。这种现象发生在数据被发送且收到ACK确认
- 右边沿向右移动将允许发送更多数据。这种现象发生在另一端接收进程读取已经确认的数据并释放了TCP的接收缓存。
2、TCP拥塞控制
传输数据的时候,如果发送方传输的数据量超过了接收方的处理能力,那么接收方会出现丢包。为了避免出现此类问题,流量控制要求数据传输双方在每次交互时声明各自的接收窗口「rwnd」大小,用来表示自己最大能保存多少数据。
2.1 慢启动- Slow Start
虽然流量控制可以避免发送方过载接收方,但是却无法避免过载网络,这是因为接收窗口「rwnd」只反映了服务器个体的情况,却无法反映网络整体的情况。
为了避免过载网络的问题,慢启动引入了拥塞窗口「cwnd」(cwnd全称Congestion Window)的概念,用来表示发送方在得到接收方确认前,最大允许传输的未经确认的数据。「cwnd」同「rwnd」相比不同的是:它只是发送方的一个内部参数,无需通知给接收方,其初始值往往比较小,然后随着数据包被接收方确认,窗口成倍扩大。
慢启动主要算法为:
- 初始化cwnd = 1,表明可以传一个MSS大小的数据
- 每收到一个ACK,cwnd++; 例如,收到第一个ack,cwnd=2,发送两个数据包,收到这两个数据包的ack,cwnd=4,为指数增加关系
- 还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”
下图说明了这个过程。
2.2 拥塞避免算法 – Congestion Avoidance
ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”。一般来说ssthresh的值是65535,单位是字节,当cwnd达到这个值时后,算法如下:
1)收到一个ACK时,cwnd = cwnd + 1/cwnd
2)当每过一个RTT时,cwnd = cwnd + 1
这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。很明显,是一个线性上升的算法。