机制
-
流量控制:根据收发端能力,控制传输量,提高传输效率。
-
拥塞控制:应对网络延时重传情况,及时调整传输量。
-
发送窗口 拥塞窗口(发送方算法控制) 接收窗口
-
发送窗口的值是swnd = min(cwnd, rwnd),也就是拥塞窗口和接收窗口中的最小值。
-
拥塞窗口 cwnd 变化的规则:只要网络中没有出现拥塞,cwnd 就会增大;但网络中出现了拥塞,cwnd 就减少
-
通过检测ACK、RTT、RTO,进行调整。通过调整拥塞窗口,辅助调整慢启动阈值,流程切换控制流量与拥塞情况。
快速重传机制
- TCP引入了一种叫Fast Retransmit 的算法,不以时间驱动,而以数据驱动重传。也就是说,如果,包没有连续到达,就ack最后那个可能被丢了的包,如果发送方连续收到3次相同的ack,就重传。Fast Retransmit的好处是不用等timeout了再重传。只解决了一个问题,就是timeout的问题,它依然面临一个艰难的选择,就是,是重传之前的一个还是重传所有的问题。未确认的报文可能最多只有2个,不会出现3个重复的ACK。
- 优先级。lost 数据段 IsLost (SeqNum),新的尚未发送的数据段,没有标记为LOST,没有标记为SACKed,没有重传过的数据段
滑动窗口
- TCP必需要解决的可靠传输以及包乱序(reordering)的问题,所以,TCP必需要知道网络实际的数据处理带宽或是数据处理速度,这样才不会引起网络拥塞,导致丢包。
- TCP头里有一个字段叫Window,又叫Advertised-Window,这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来。两个窗口由缓冲区大小决定
- TCP是双工的协议,会话的双方都可以同时接收、发送数据。TCP会话的双方都各自维护一个"发送窗口"和一个"接收窗口"。其中各自的"接收窗口"大小取决于应用、系统、硬件的限制(TCP传输速率不能大于应用的数据处理速率)。各自的"发送窗口"则要求取决于对端通告的"接收窗口",要求相同。
拥塞处理
- TCP通过Sliding Window来做流控(Flow Control),但是TCP觉得这还不够,因为Sliding Window需要依赖于连接的发送端和接收端,其并不知道网络中间发生了什么。TCP的设计者觉得,一个伟大而牛逼的协议仅仅做到流控并不够,因为流控只是网络模型4层以上的事,TCP的还应该更聪明地知道整个网络上的事。
- 具体一点,我们知道TCP通过一个timer采样了RTT并计算RTO,但是,如果网络上的延时突然增加,那么,TCP对这个事做出的应对只有重传数据,但是,重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,于是,这个情况就会进入恶性循环被不断地放大。试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成"网络风暴",TCP这个协议就会拖垮整个网络。这是一个灾难。
- 对此TCP的设计理念是:TCP不是一个自私的协议,当拥塞发生的时候,要做自我牺牲。就像交通阻塞一样,每个车都应该把路让出来,而不要再去抢路了。
- 发送方维持一个拥塞窗口 cwnd 的状态变量。发送方让自己的发送窗口小于等于拥塞窗口。
拥塞处理算法
- 慢开始 :由小到大的逐渐增大拥塞窗口。首先将cwnd设置为一个最大报文段MMS,在收到一个对新的报文段的确认后,把拥塞窗口增加一个MMS。
- 拥塞避免 :当慢开始到门限值 ssthresh(slow start threshold 慢启动阈值)后,使用拥塞避免算法(cwnd每次加1)。当发现网络拥塞后,将cwnd置为1,ssthresh减半,再次执行慢开始。
- 快重传 :当接收方收到一个失序报文段后就立即发送重复确认而不要等到自己发送数据时捎带确认。当发送方连续收到三个重复确认时,应立即重传接收方尚未收到的报文段。
- 拥塞快恢复 :与快重传结合使用。
- 在连续收到三个重复确认时,将慢开始的ssthresh减半,这是为了防止网络拥塞(接下来并不执行慢开始 )。
- 由于发送方现在认为网络很可能没有拥塞,于是接下来不执行慢开始,而是将cwnd值设置为ssthresh减半后的值,然后执行拥塞避免。