分类: 系统运维
2010-08-17 21:13:47
超时重传是TCP协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
超时时间的计算是超时的核心部分,TCP要求这个算法能大致估计出当前的网络状况,虽然这确实很困难。要求精确的原因有两个:(1)定时长久会造成网络利用率不高。(2)定时太短会造成多次重传,使得网络阻塞。所以,书中给出了一套经验公式,和其他的保证计时器准确的措施。
最早的TCP曾经用了一个非常简单的公式来估计当前网络的状况,如下
其中a是一个经验系数为0.1,b通常为2。注意,这是经验,没有推导过程,这个数值是可以被修改的。这个公式是说用旧的RTT(R)和新的 RTT(M)综合到一起来考虑新的RTT(R)的大小。但是,我们又看到,这种估计在网络变化很大的情况下完全不能做出“灵敏的反应” (Jacoboson说的,不是偶说的,呵呵),于是就有下面的修正公式:
具体的解释请看书的228页,这个递推公式甚至把方差这种统计概念也使用了进来,使得偏差更加的小。而且,必须要指出的是,这两组公式更新,都是在 数据成功传输的情况下才进行,在发生数据重新传输的情况下,并不使用上面的公式进行网络估计,理由很简单,因为程序已经不在正常状态下了,估计出来的数据 也是没有意义的。
RTO的初始化是由公式决定的,例如最初的公式,初始的值应该是1。而修正公式,初始RTO应该是A+4D。
当数据正常传输的情况下,我们就会用上面的公式来更新各个数据,并重开定时器,来保证下一个数据被顺利传输。要注意的是:重传的情况下,RTO不用上面的公式计算,而采用一种叫做“指数退避”的方式。例如:当RTO为1S的情况下,发生了数据重传,我们就用RTO=2S的定时器来重新传输数据,下一次用4S。一直增加到64S为止。
在这里,SYN用的估计器初始化似乎和传输用的估计器不一样(我也没有把握)造我的理解,在修正公式中,SYN的情况下,A初始化为0,D初始化为3S。
而在得到传输第一个数据的ACK的时候,应该按照下面的公式进行初始化:
和上面的讨论差不多,就是在正常情况下,用上面的公式计算,在重传的情况下,不更新估计器的各种参数。原因还是因为估计不准确。
这不算是一个算法,这应该是一个策略,说的就是更新RTO和估计器的值的时机选择问题,1.3.和1.5.所说得更新时机就是Karn算法。
两句话:
有了超时就要有重传,但是就算是重传也是有策略的,而不是将数据简单的发送。
前面曾经提到过,数据在传输的时候不能只使用一个窗口协议,我们还需要有一个拥塞窗口来控制数据的流量,使得数据不会一下子都跑到网路中引起“拥 塞”。也曾经提到过,拥塞窗口最初使用指数增长的速度来增加自身的窗口,直到发生超时重传,再进行一次微调。但是没有提到,如何进行微调,拥塞避免算法和 慢启动门限就是为此而生。
所谓的慢启动门限就是说,当拥塞窗口超过这个门限的时候,就使用拥塞避免算法,而在门限以内就采用慢启动算法。所以这个标准才叫做门限,通常,拥塞窗口记做cwnd,慢启动门限记做ssthresh。下面我们来看看拥塞避免和慢启动是怎么一起工作的
算法概要(直接从书中拷贝)
补充上面的拥塞避免公式在P238页。这整个的流程让我联想到开车换档的过程。
这是数据丢包的情况下给出的一种修补机制。一般来说,重传发生在超时之后,但是如果发送端接受到3个以上的重复ACK的情况下,就应该意识到,数据丢了,需要重新传递。这个机制是不需要等到重传定时器溢出的,所以叫做快速重传,而重新传递以后,因为走的不是慢启动而是拥塞避免算法,所以这又叫做快速恢复算法。流程如下:
答案是:不会,TCP会坚持用自己的定时器,但是TCP会保留下ICMP的错误并且通知用户。
TCP为了提高自己的效率,允许再重新传输的时候,只要传输包含重传数据报文的报文就可以,而不用只重传需要传输的报文。