RTT:往返时间; RTO:Retransmission Timeout即超时重传时间;
关键点在于:超时和重传间隔的策略,即怎样确定超时间隔和重传间隔;
TCP中的四个定时器:2MSL定时器;重传定时器;坚持定时器;保活定时器;
首先是如何得到RTO值;(假设已经能测量到RTT值情况下)
RTO值是依赖RTT值来确定的;而鉴于网络环境的不稳定性,RTT总是变化的,
RTT = 0.1*M + 0.9*R; M:当前测试的RTT值,R:历史RTT的值;
RTO=@RTT; @:一般取2;
详解过程参见RFC793,但是该方法是有缺陷的;
新的方法:
Err = M - A; M:当前RTT值, A:历史RTT值;
平均值:A = A+gErr; A:历史RTT值, g:常量,
方差:D = D + h(|Err| - D); D:历史D的值,h:常量
(重点):RTO = A + 4D;
RTO的初始化: A=0; D=3;(即没有测的RTT情况下)
当数据正常传输的情况下,我们就会用上面的公式来更新各个数据,并重开定时器,来保证下一个数据被顺利传输。要注意的是:重传的情况下,RTO不用上面的公式计算,而采用一种叫做“指数退避”的方式。例如:当RTO为1S的情况下,发生了数据重传,我们就用RTO=2S的定时器来重新传输数据,下一次用4S。一直增加到64S为止。
(也就是说:1、计时器计算是否超时是用的是几乎时时更新的RTO(估计器)时间,而重传时间间隔采用的是“指数退避(exponential backoff)“时间,
2、并且在重传的情况下,不更新估计器的各种参数,
上述两点就是所谓的 Karn算法
);
估计器的更新:
示例:
1、传SYN:
传输初始SYN所使用的RTO:RTO = A + 2D = 6s; (这个公式以后不再用了)
2、上述SYN丢失了;然后超时了;因为6s内没有收到ACK;
计算当前的RTO: RTO=A + 4D = 0 + 4×3 = 12s
由于这是第一次超时,我们使用的倍数是2^0;RTO = 2^0*12 = 12s
拥塞避免算法与慢启动算法的结合:
原因:数据在传输的时候不能只使用一个窗口协议,我们还需要有一个拥塞窗口来控制数据的流量,使得数据不会一下子都跑到网路中引起“拥塞”。曾经提到过,拥塞窗口最初使用指数增长的速度来增加自身的窗口,直到发生超时重传,再进行一次微调。但是没有提到,如何进行微调,拥塞避免算法和慢启动门限就是为此而生。
拥塞避免算法和慢启动算法需要对每个连接维持两个变量:
一个拥塞窗口cwnd, 和 一个慢启动门限ssthresh;它们的工作过程如下:
1、对一个给定的连接,初始化cwnd为1个报文段,ssthresh为2^16=65535个字节;
2、此时TCP输出的报文段不能超过cwnd和接收方通告窗口的大小,拥塞避免是c方使用的流量控制,通告窗口则是s方进行的流量控制,
拥塞避免是c方感受到网络拥塞的估计;通告窗口与s方在该连接上的缓存大小有关;
3、当拥塞发生时(超时或者收到重复的ACK;都表明丢包了), ssthresh被设置为当前窗口大小的一半(当前窗口即cwnd和通告窗口两者中的小值,但最少为2个报文段),
如果是超时引起的拥塞,则cwnd被设置为1个报文段(这就是慢启动)
4、当新的数据被对方确认时,就增加cwnd,但增加的方法依赖于我们是否正在进行慢启 动或拥塞避免。如果cwnd小于或等于ssthresh,则正在进行慢启动,否则正在进行拥塞避免。 慢启动一直持续到 我们回到当拥塞发生时所处位置的半时候才停止(因为我们记录了在步骤2 中给我们制造麻烦的窗口大小的一半),然后转为执行拥塞避免。
这是数据丢包的情况下给出的一种修补机制。一般来说,重传发生在超时之后,但是如果发送端接受到3个以上的重复ACK的情况下,就应该意识到,数据丢了,需要重新传递。这个机制是不需要等到重传定时器溢出的,所以叫做快速重传,而重新传递以后,因为走的不是慢启动而是拥塞避免算法,所以这又叫做快速恢复算法。流程如下:
答案是:不会,TCP会坚持用自己的定时器,但是TCP会保留下ICMP的错误并且通知用户。
TCP为了提高自己的效率,允许再重新传输的时候,只要传输包含重传数据报文的报文就可以,而不用只重传需要传输的报文。