【lwip】12-一文解决TCP原理( 六 )

  • 禁用了Nagle算法时,可发送 。
  • 12.8 拥塞控制&一些可靠算法拥塞:当数据从一个大的管道(如一个快速局域网)向一个较小的管道(如一个较慢的广域网)发送时便会发生拥塞 。发送拥塞后,发送端并不知道哪里发送拥塞而被丢弃数据,只能等待超时重传,这个将会非常耗时,而且会重新进入慢启动和降低上门限值ssthresh 。所以需要尽量避免超时重传 。
    拥塞控制:避免出现拥塞 。
    拥塞控制算法包括慢启动、拥塞避免、拥塞发生(超时重传、快重传)、快恢复 。
    这几种算法下面会介绍到 。
    12.8.1 RTT和RTO计算RTT(Round Trip Time):一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值;RTO(Retransmission Time Out):重传超时时间,即从数据发送时刻算起,超过这个时间便执行重传 。RTT和RTO 的关系是:由于网络波动的不确定性,每个RTT都是动态变化的,所以RTO也应随着RTT动态变化 。
    12.8.1.1 RTT测量两种方法:
    1. 方法一:TCP Timestamp选项:TCP时间戳选项可以用来精确的测量RTT:RTT = 当前时间 -数据包中Timestamp选项的回显时间 。这个回显时间是该数据包发出去的时间,知道了数据包的接收时间(当前时间)和发送时间(回显时间),就可以轻松的得到RTT的一个测量值 。
    2. 方法二:选择一个指定SEQ的数据包,在发出时记录系统当前时间,在收到该SEQ的ACK后,用当前时间 减 发出时的时间就是本次RTT 。
    12.8.1.2 RTT估计器每次测量RTT都会有差异,所以我们需要平滑下 。
    假设每次实测的RTT值为SampleRTT 。
    估计RTT值为EstimatedRTT 。
    TCP会通过多次SampleRTT来维护EstimatedRTT 。
    算法:EstimatedRTT = (1-a)* EstimatedRTT + a * SampleRTT
    • 其中a通常取值为0.125
    12.8.1.3 RTT方差在最初的RTO算法中,RTO等于一个值为2的时延离散因子与RTT估计值的乘积,即:
    • RTO = 2 * EstimatedRTT
    但这种做法有个很大的缺陷,就是在RTT变化范围很大的时候,使用这个方法无法跟上这种变化,从而引起不必要的重传 。
    由于新测量SampleRTT的权值只占EstimatedRTT的12.5%(通常情况下),当实际RTT变化很大的时候,即便测量到的SampleRTT变化也很大,但是所占比重小,最后EstimatedRTT的变化也不大,从而RTO的变化不大,造成RTO过小,容易引起不必要的重传 。因此对RTT的方差跟踪则显得很有必要 。
    在TCP规范中定义了RTT偏差DevRTT,用于估算SampleRTT一般会偏离EstimatedRTT的程度:
    • DevRTT = (1-B) * DevRTT + B * |SampleRTT - EstimatedRTT|
      • 其中B的推荐值为0.25,当RTT波动很大的时候,DevRTT的就会很大 。
    12.8.1.4 RTO值计算超时重传时间间隔RTO的计算公式为:RTO = EstimatedRTT + 4 * DevRTT
    在[RFC 6298]中,推荐初始超时重传时间为1秒,当出现超时后,超时重传时间将以指数退避的方法加倍,以免即将被确认的后继报文段过早出现超时 。
    12.8.2 慢启动在设备启动往网络上发送数据时,并不知道网络状况,所以进行试探,发少量数据在逐步增加数据量 。
    慢启动为发送方的 TCP增加了另一个窗口:拥塞窗口 (congestion window),记为cwnd 。
    拥塞窗口初始化为1个报文段(1个MSS) 。每收到一个报文段的ACK,拥塞窗口就增加大一个报文段 。收到两个,就增大两个 。
    【lwip】12-一文解决TCP原理

    文章插图
    12.8.3 拥塞避免当拥塞窗口增大到慢开始上门限值ssthresh时,就开始拥塞避免算法 。每次只增加一个报文段 。

    经验总结扩展阅读