TCP提供可靠的运输层。它使用的方法之一就是确认从另一端收到的数据。但数据和确认都有可能会丢失。TCP通过在发送时设置一个定时器来解决这种问题。如果当定时器溢出时还没有收到确认,它就重传该数据。

对于实现而言,关键之处就在于超时和重传的策略,即怎样决定超时间隔和如何确定重传频率

TCP管理4种不同的定时器:

  • 重传定时器:当希望收到另一端的确认时使用。
  • 坚持定时器:使窗口信息保持不断流动,即使另一端关闭了其接收窗口。
  • 保活定时器:检测一个空闲连接的另一端何时崩溃或重启。
  • 2MSL定时器:测量一个连接处于TIME_WATI状态的时间。

指数退避:书中检查连续重传之间不同的时间差,它们取整后分别是1、3、6、12、24、48和多个64秒,其中第一次发送后设置的超时时间设置为1.5秒。(2的N次方*1.5秒)

1.往返时间测量

RTT(往返时间):指发送端发送TCP报文段开始到接收到对方的确定所使用的时间。

TCP超时与重传中最重要的部分就是对一个给定连接的往返时间的测试。由于路由器和网络流量均会变化,因此我们认为这个时间可能经常会发生变化,TCP应该跟踪这些变化并相应地改变其超时时间。

RTO(超时重传时间):发送端发送TCP报文段后,在RTO时间内没有收到对方确定,即重传该报文段。

最早的TCP曾经用了一个非常简单的公式来估计当前网络的状况,如下:

R<-aR+(1-a)M
RTP=Rb

其中a是一个经验系数为0.9,称为平滑因子,b通常为2。这个数值是可以被修改的。这个公式是说用旧的RTT(R)和新的RTT(M)综合到一起来考虑新的RTT(R)的大小。每次进行新测量时,这个被平滑的RTT将得到更新。每个新估计的90%来自前一个估计,而10%则取自新的测试。

但是,在RTT变化范围很大时,使用这个方法无法跟上这种变化,从而引起不必要的重传。当网络已经处于饱和状态时,不必要的和重传会增加网络的负载,对网络而言就像在火上浇油。于是就有下面的修正公式:

Err=M-A
A<-A+gErr
D<-D+h(|Err|-D)
RTO=A+4D
  • A 平滑的RTT(均值估计器)
  • D 平滑的方差
  • g 增量
  • h 方差的增益

RTO值基于RTT的均值和方差,这更好的响应了RTT的变化。

karn算法(重传多义性)

假如发送一个分组,当发生超时,RTO指数退避,重传该分组,然后收到ACK。此时但并不能确定这个ACK是针对第一个分组还是重传分组,这就是重传多义性问题。

karn算法针对这个问题

(1)对于超时重传的数据报的确认,不更新RTT。
(2)要注意的是:重传的情况下,RTO不用上面的公式计算,而采用一种叫做“指数退避”的方式。RTO指数退避,下一次传送就使用这个RTO值。
(3)重传数据确认之后,再次发送的数据如果正常被确定,恢复Jacobson 1988公式,更新RTO和RTT。

2.拥塞避免算法

该算法假定由于分组受到损坏引起的丢失是非常少的,因此分组丢失就意味着源主机和目的主机之间的某处网络上发生了拥塞。有两种分组丢失的指示:

  • 发生超时
  • 接收到重复的确认

数据在传输的时候不能只使用一个窗口协议,我们还需要有一个拥塞窗口来控制数据的流量,使得数据不会一下子都跑到网路中引起“拥塞”。也曾经提到过,拥塞窗口最初使用指数增长的速度来增加自身的窗口,直到发生超时重传,再进行一次微调。但是没有提到,如何进行微调,拥塞避免算法和慢启动门限就是为此而生。

所谓的慢启动门限就是说,当拥塞窗口超过这个门限的时候,就使用拥塞避免算法,而在门限以内就采用慢启动算法。所以这个标准才叫做门限,通常,拥塞窗口记做cwnd,慢启动门限记做ssthresh。下面我们来看看拥塞避免和慢启动是怎么一起工作的。

拥塞避免算法和慢启动算法是两个目的不同、独立的算法。我们希望降低分组进入网络的传输速率,于是可以调用慢启动来作到这一点,拥塞避免算法和慢启动算法通常一起使用:
每个连接维持两个变量: 拥塞窗口( cwnd )  慢启动门限( ssthresh )[下图中假设为16]

算法概要:

  1. 对一个给定的连接,初始化cwnd为1个报文段,ssthresh为65535个字节。
  2. TCP输出例程的输出不能超过cwnd和接收方通告窗口的大小。拥塞避免是发送方使用的流量控制,而通告窗口则是接收方进行的流量控制。前者是发送方感受到的网络拥塞的估计,而后者则与接收方在该连接上的可用缓存大小有关。
  3. 当拥塞发生时(超时或收到重复确认),ssthresh被设置为当前窗口大小的一半[下图中的12](cwnd 和接收方通告窗口大小的最小值,但最少为2个报文段)。此外,如果是超时引起了拥塞,则 cwnd被设置为1个报文段(这就是慢启动)。
  4. 当新的数据被对方确认时,就增加cwnd,但增加的方法依赖于我们是否正在进行慢启动或拥塞避免。如果cwnd小于或等于ssthresh,则正在进行慢启动,否则正在进行拥塞避免。 慢启动一直持续到我们回到当拥塞发生时所处位置的半时候才停止(因为我们记录了在步骤2 中给我们制造麻烦的窗口大小的一半),然后转为执行拥塞避免。


cwnd增加方式
慢启动初始cwnd为1,每收到一个确定就加1,成指数增长。
拥塞避免算法在每个RTT内增加 1/cwnd 个报文,成线性增长。
慢启动根据收到的ACK次数增加cwnd,而拥塞避免算法在一个RTT不管收有多少ACK也只增加一次。

3.快速重传和快速恢复算法

如果收到3个重复ACK,可认为该报文段已经丢失,此时无需等待超时定时器溢出,直接重传丢失的包,这就叫快速重传算法。而接下来执行的不是慢启动而是拥塞避免算法,这就叫快速恢复算法。
(1)当收到第3个重复的ACK时,将ssthresh设置为当前拥塞窗口cwnd的一半,重传丢失的报文段,设置cwnd为ssthresh加上3倍的报文段大小。
(2)每次收到另一个重复的ACK时,cwnd增加1个报文段大小并发送1个分组(如果新的cwnd允许发送)。
(3)当下一个确认新数据的ACK到达时,设置cwnd为ssthresh(在第1步中设置的值)。这个ACK应该是在进行重传后的一个往返时间内对步骤1中重传的确认。另外,这个ACK也应该是对丢失的分组和收到的第1个重复的ACK之间的所有中间报文段的确认。这一步采用的是拥塞避免,因为当分组丢失时我们将当前的速率减半。


4.ICMP(Internet Control Message Protocol)Internet控制报文协议)差错

TCP能够遇到的最常见的ICMP差错就是源站抑制、主机不可达和网络不可达。

(1)源站抑制的ICMP将拥塞窗口cwnd置为1个报文段,并发起慢启动,慢启动门限ssthresh不变,窗口将打开直至开放了所有的通路(受窗口大小和往返时间的限制)或者发生了拥塞。

(2)主机不可达或网络不可达的ICMP将被忽略,因为这两上差错都被认为是短暂现象。

5.重新分组

当TCP超时并重传时,它不一定需要重传同样的报文段。相反,TCP允许进行重新分组而发送一个较大的报文段,这将有助于提高性能(当然,这个较大的报文段不能够超过接收方声明的MSS)

 

13.TCP的超时与重传的更多相关文章

  1. 【TCP/IP详解 卷一:协议】第二十一章 TCP的超时与重传

    作为TCP的重头戏,本章节涉及了许多关于计算方面的内容,使用了大量的例子来指明一些观点. 我使用的理解方法是:通过别人的博客,以及实例结合进行理解,不然会很吃力. 21.1 引言 reliable T ...

  2. TCP之超时和重传

    RTT:往返时间:  RTO:Retransmission Timeout即超时重传时间: 关键点在于:超时和重传间隔的策略,即怎样确定超时间隔和重传间隔: TCP中的四个定时器:2MSL定时器:重传 ...

  3. TCP/IP详解 卷1 第二十一章 TCP的超时与重传

    21.1 引言 可靠性的保证之一就是超时重传 前面两个超时重传的例子 1)  ICMP端口不能到达时,TFTP客户使用UDP实现了一个简单的超时和重传机制,假定5s是一个适当是时间间隔,并每隔5s进行 ...

  4. TCP/IP协议--TCP的超时和重传

    TCP是可靠传输.可靠之一体现在收到数据后,返回去一个确认.但是不能完全避免的是,数据和确认都可能丢失.解决这个办法就是,提供一个发送的重传定时器:如果定时器溢出时还没收到确认,它就重传这个报文段. ...

  5. TCP的超时与重传

    一.引言 对于每个TCP连接,TCP管理4个不同的定时器 重传定时器用于当希望收到另一端的确认. 坚持 (persist) 定时器使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口. 保活 (ke ...

  6. 《TCP/IP具体解释》读书笔记(21章)-TCP的超时与重传

    TCP提供可靠的运输层. 它使用的方法之中的一个就是确认从还有一端收到的数据.但数据和确认都有可能会丢失.TCP通过在发送时设置一个定时器来解决这样的问题.假设当定时器溢出时还没有收到确认,它就重传该 ...

  7. 【TCP】超时与重传

    在TCP连接中假设发送方一开始便向网络发送多个报文段,直到达到接收方通告的窗口大小为止.当发送方和接收方处于同一个区域网段时,这种方式是可以的.但是如果发送方和接收方之间存在多个路由器和速率较慢的链路 ...

  8. TCP/IP详解学习笔记(12)-TCP的超时与重传

    超时重传是TCP协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止. 1.超时 超 ...

  9. TCP/IP具体解释学习笔记--TCP的超时与重传

    1.基本概念 TCP之所以能够安全的将数据在传输中的安全性,是因为它每次给对方发送数据,都会等待对方给个确认,当长时间收不到这个确认,发送端就会重发这个数据. 2.超时时间的測量 要測超时时间,TCP ...

随机推荐

  1. 自定义solr的search UI

    solr使用apache的velocity来定义UI,在solr的search ui的基础上更改即可,主要改\example\solr\collection1\conf\velocity里的文件. 详 ...

  2. C#入门经典-第15章ListBox,CheckedListBox

  3. oracle数据库兼容mysql的差异写法

    1.sysdate改为sysdate(),或者now(); 2.nvl(expr1,expr2) 改为IFNULL(expr1,expr2) nvl2(expr1,expr2,expr3)改为 IF( ...

  4. android脚步---Itent.ACTION_PICK ,startActivityForResult

    public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(Intent.A ...

  5. POJ 3984 迷宫问题 记录路径的广搜

    主要是学一下如何在广搜中记录路径:每找到一个点我就记录下这个点是由那个点得来的,这样我找到最后个点后,我就可以通过回溯得到我走过的路径,具体看代码吧~ #include<cstdio> # ...

  6. QWidget QMainWindow QDialog 三个基类的区别

    Qt类是一个提供所需的像全局变量一样的大量不同的标识符的命名空间.通常情况下,你可以忽略这个类.QObject和一些其它类继承了它,所以在这个Qt命名空间中定义的所有标识符通常情况下都可以无限制的使用 ...

  7. jquery奇怪的问题

    Jquery中 $("#data_table4 tr:eq(0)").after("<tr><td>" +result+data.row ...

  8. Source

    转载自:http://blog.csdn.net/u014084081/article/details/44617707 Guide iOS Developer Library 教程 Ray Wend ...

  9. Android CTS 测试总结【转】

    Android CTS 测试总结[转] 最近一直在做Android兼容性测试,根据Android官网给出的android-cts-manual 配置好了device后,开始测试. 首先配置软件环境: ...

  10. Posix消息队列实现机制

    本文是对<Unix 网络编程 卷2:进程通信>的笔记. 引言 消息队列是进程间通信的一种方式,可是如果不理解他的实现原理,会有众多不理解之处,下面就结合本书中的例子,对posix消息队列来 ...