从上一篇示例中我们可以看到在TCP中有一个重要的过程就是决定何时进行超时重传,也就是RTO的计算更新。由于网络状况可能会受到路由变化、网络负载等因素的影响,因此RTO也必须跟随网络状况动态更新。如果TCP过早重传,则可能会向网络中注入很多重复报文,如果过晚重传,则在丢包时候则会影响滑窗前行可能会降低网络利用率。因为TCP在接收到数据后会发送累计的ACK number,因此TCP发送某个系列号的报文后,在接收到覆盖此系列号的ACK报文的时候,测量发送和接收之间的时间,这个测量就叫做RTT采样(RTT sample)。TCP对于每个连接都会根据RTT采样来维护跟新RTO,同时还会维护一个RTO超时的定时器。注意是对每个连接维护一个超时定时器,而不是对每个发出去的TCP报文。当TCP发出数据报文(或者SYN、FIN报文)的时候,如果之前没有等待ACK的报文则会设置这个连接的RTO定时器,如果之前有等待ACK的报文,则并不会重启RTO定时器。当TCP同时有多个报文发出且没有等到ACK的时候,则会先重传第一个报文,第一个报文重传成功收到ACK后,再设置RTO定时器然后重传第二个报文。

本篇先来介绍一下协议中更新计算RTO的方法。协议中主要有两种方法来计算RTO一种是RFC793的经典方法(classic method),另一种是RFC6298的标准方法(standard method)。

一、经典方法

在原始的RFC793中关于RTO更新的介绍只有半页文字的样子,它首先让TCP使用下面的公式更新一个平滑RTT估计(smoothed RTT estimator、简称SRTT):

SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT)

其中RTT是之前介绍的一个RTT采样值,ALPHA则是一个平滑因子(smoothing factor),协议给出的示例范围是0.8--0.9之间。这个过程也叫做指数加权移动平均(exponentially weighted moving average、简称EWMA)。可以看到这个计算过程只需要保留一个RTT采样值就行了,而不需要保留过多的历史RTT采样。

接着在按照下面公式计算出RTO:

RTO = min[UBOUND,max[LBOUND,(BETA*SRTT)]]

其中BETA是一个延迟因子,协议给出的示例范围是1.3--2.0。UBOUND是一个RTO上限,LBOUND是一个RTO下限,UBOUND和LBOUND协议给出的示例范围分别是1分钟和1秒,显然这两个值对于现代TCP网络可能并不合适。

二、标准方法

RFC1122指出上面介绍的计算RTT的经典方法中存在两个问题,一个是在发生TCP重传的时候,RTT采样的精确测量非常困难,第二个问题是经典方法认为RTT是比较平稳的状态,变化比较小,因此SRTT的计算是不合适的。实际上比如在低速网络中,TCP的数据包的不同大小会导致不同的传输耗时,进而可能就会导致RTT采样值差距比较大。对于上面两个问题第一个问题由karn算法解决,karn算法我们后续进行介绍。第二个问题由Jacobson算法解决,该算法在RTO估计中添加了一个用于反映RTT波动的RTTVAR变量。而RFC6298就是一个基于Jacobson算法的RTO计算文档,我们把这种RTO计算方法称为标准方法。

1、RTO计算及更新

为了计算当前的RTO,TCP发送端维护两个状态变量一个是SRTT(smoothed round-trip time)一个是RTTVAR (round-trip   time variation),另外还有一个TCP时钟粒度G。

1)、在没有测量到有效的RTT采样之前,设置RTO=1s;

2)、在第一个有效的RTT采样测量出来后,假设采样值为R,则进行如下初始化过程

SRTT = R

RTTVAR = R/2

RTO = SRTT + max(G,K*RTTVAR)

其中K = 4;

3)、当随后的RTT采样R’测量到以后,按照如下更新:

RTTVAR = (1 - beta) * RTTVAR + beta * |SRTT - R'|

SRTT = (1 - alpha) * SRTT + alpha * R'

注意用于计算RTTVAR的公式中的SRTT是本次更新前的值,也就是说这两个公式的计算顺序不能颠倒。其中alpha=1/8、 beta=1/4,alpha和beta的选值允许计算机通过移位做除法的快速运算。

计算出SRTT和RTTVAR后,RTO仍旧按照如下更新:

RTO = SRTT + max (G, K*RTTVAR)

4)、当RTO计算出来后,如果RTO小于1s,RTO则应该设置为1s。虽然给出的是1s的下限,但是协议允许使用更低的下限。

5)、也可以对RTO设置一个上限,协议建议上限至少为60s。

关于上面的RTT采样,协议要求使用karn算法进行采样,同时要求至少在一个RTT里面采样一次(除非因为karn算法导致不可能在一个RTT里面采样一次)。协议指出对于每个TCP报文进行RTT采样测量不一定会得到更好的RTT估计值。

2、RTO定时器的管理

协议对于RTO定时器的建议管理方法如下:

1)、每次一个包含数据的TCP报文发送出去的时候(包括重传),如果RTO定时器没有运行,则重启RTO定时器,并设置定时时间为RTO。

2)、当所有发出的数据报文都被ACK后,关闭这个RTO定时器。

3)、当一个新的ack number到达的时候(新的ack number是指ack了新数据),如果还有未被ACK的数据,则重启RTO定时器,并设置定时时间为当前RTO。

当RTO定时器触发的时候(即所设置的定时时间到达的时候)

4)、在还没有ACK的报文里面重传最早发出去的报文。

5)、设置RTO = RTO * 2,这也就是我们经常说的指数回退。也可以和上面RTO更新过程一样添加一个同样的上限来限制RTO大小。

6)、重启RTO定时器,设置定时时间为RTO(这里的RTO是已经回退过的RTO)。

7)、如果RTO定时器是因为等待SYN报文的ACK而超时,如果实现上使用的RTO值小于3s,这个RTO定时器必须被重新初始化为3s。

在重传完成后,新的RTT采样可能会将RTO设置为与原来比较接近的值,从而消除指数回退对于RTO的影响。另外在多次指数回退过程中,TCP实现可能会清空SRTT和RTTVAR的值,一旦这两个被清空,则需要使用上面RTO计算及更新中的第2)步来初始化SRTT和RTTVAR。

三、RTO定时器管理示例

下面的测试示例关闭了TLP功能,相关介绍见后面文章

1、RTO超时重传成功恢复后发送的新数据又RTO超时。对于这种场景我们从下图可以看到新发送的数据在RTO超时后,超时时间大约为1.5s,也就是说RTO定时器在之前指数回退后现在已经恢复。

2、RTO超时重传collapse后,只回复部分ACK确认包。如下图所示,在数据包No6超时重传的时候,把No7数据包collapse在一起了,也就是说No8重传包同时包含了No6和No7数据包的内容,从图中的len字段也可以看出来,如果这时候client只是ACK确认了No6报文的内容(No12确认包Ack=1740381487正好是No7数据包的Seq),No11重传包只有收到Ack>=1740381493时候才会取消RTO定时器,这时候部分ACK并不能取消server在发送No11时候的定时器,最终RTO超时超时重传No13数据包,重传的时候被部分ACK确认的数据不会在重传,因为No13只是重传了No7数据包。(关于重传collapse的内容我们后面内容在进行介绍)。

3、RTO超时重传成功后还有待重传数据。如下图所示,server端发出了No6和No7两个数据包,RTO超时后重传No6报文,No6重传成功后server端发现还有一个No7报文等待重传,接着在收到No11确认包后立即进行了一个快速重传。(严格的说应该叫做慢启动重传SlowStartRetrans,但是实际上走的是快速重传的流程,快速重传请参考后面的内容)。快速重传的同时会初始化一个RTO定时器,如果快速重传失败,接着进行RTO超时重传(No13-No17)。这里可以看到server端在发出No12报文时候初始化的RTO定时器定时时间为1.5s。也就是之前RTO指数回退的作用已经消除了,可以看到这里与协议是存在一些差异的。

4、SACK reneging下RTO超时重传的示例请参考后面SACK和FACK相关的内容。

TCP系列15—重传—5、Linux中RTO的计算

之前我们介绍的都是协议中给出的RTO计算方法,下面我们看一下linux实现中RTO的计算方法.在linux中维护了srtt.mdev.mdev_max.rttvar.rtt_seq几个状态变量用来计算 ...

TCP系列25—重传—15、DSACK虚假重传探测

一.DSACK介绍 RFC2883通过指定使用SACK来指示接收端的重复包(duplicate packet)扩展了RFC2018对SACK选项的定义(SACK选项的介绍和示例参考前面内容).RFC2 ...

TCP系列11—重传—1、TCP重传概述

在最开始介绍TCP的时候,我们就介绍了TCP的三个特点,分别是面向连接.可靠.字节流式.前面内容我们已经介绍过了TCP的连接管理,接下来的这部分内容将会介绍与TCP可靠性强关联的TCP重传. 很多网络 ...

TCP系列24—重传—14、F-RTO虚假重传探测

一.虚假重传 在一些情况下,TCP可能会在没有数据丢失的情况下初始化一个重传,这种重传就叫做虚假重传(Spurious retransmission).发生虚假重传的原因可能是包传输中重排序.传输中发 ...

TCP系列16—重传—6、基础快速重传(Fast Retransmit)

一.快速重传介绍 按照TCP协议,RTO超时重传是一个非常重要的事件,当RTO超时的时候,TCP会同时通过两种方式非常谨慎的降低发送数据包的速率,一种是基于拥塞控制削减发送窗口的大小,另外一个是通过指 ...

TCP系列14—重传—4、Karn算法和TSOPT的RTTM

一.Karn算法 在RTT采样测量过程中,如果一个数据包初传后,RTO超时重传,接着收到这个数据包的ACK报文,那么这个ACK报文是对应初传TCP报文还是对应重传TCP报文呢?这个问题就是retran ...

TCP系列21—重传—11、TLP

一.介绍 Tail Loss Probe (TLP)是同样是一个发送端算法,主要目的是使用快速重传取代RTO超时重传来处理尾包丢失场景.在一些WEB业务中,如果TCP尾包丢失,如果依靠RTO超时进行重 ...

TCP系列01—概述及协议头格式

一.TCP简单介绍 我们经常听人说TCP是一个面向连接的(connection-oriented).可靠的(reliable).字节流式(byte stream)传输协议,  TCP的这三个特性该怎么 ...

TCP系列12—重传—2、Linux超时重传引入示例

在前面我们概述了TCP的超时重传之后我们简单的看一下tcp超时重传的示例.首先简单的描述一下测试过程 1.设置/proc/sys/net/ipv4/tcp_early_retrans为2,关掉TLP功 ...

随机推荐

国内可用maven repository 配置

国内可用maven repository 配置 发表于2016/1/4 23:08:04  10235人阅读 分类: maven 鉴于一些原因,从maven中央仓库download依赖包时,被各种折磨 ...

浮出层的css写法,完美兼容IE6~10

利用元素间的绝对定位差一像素,使用不同颜色做出浮出层小三角的效果,完美兼容各浏览器! html部分:

搭建Android环境

1.相关文件下载: 1.1.Java jdk下载: JDK下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jre7-downl ...

关于Oracle数据库字符集的选择

如果数据库只在中国地区使用,数据库字符集选择ZHS16GBK或者常用中文字符集,如果不确定,就推荐使用AL32UTF8 国家字符集就选择: AL16UTF16 字符集一旦设定,不允许修改,修改可能出现 ...

Spring Framework AOP具体解释

此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.近期项目中遇到了下面几点需求,细致思考之后,认为採用AOP来解决.一方面是为了以更加灵活的方式来解决这个问题,还有 ...

css居中问题

学习过程中遇到css居中问题 , 也查阅了资料,每个人的方法都不尽相同,而且当时看懂了,过后就记混淆了;so作为一个前端小白,也来写一下俗话说好脑子不如烂笔头,毕竟自己知道的也不多,其实是抱着学习和交 ...

Java开发知识之Java的异常处理

Java开发知识之Java的异常处理 一丶异常概述 在讲解异常之前,我们要搞清楚.什么是异常. 通俗理解就是我们编写的程序出问题了.进行处理的一种手段. 比如我们的QQ.有的时候就崩溃了.比如出现xx ...

C# - 操作符

操作符(Operator) C#的操作符是一种告诉编译器执行计算.逻辑判断的符号. default(x) 获取类型的默认值,x是类型.虽然可以为任意类型使用此操作符,但此操作符主要用于泛型,在不确定泛 ...

Python学习(三十九)—— Django之Form组件

一.构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的模板:

Python flask+react+antd实现登陆demo

这两天在研究flask和antd,想把这俩个东西结合来使用,单独学antd的时候用的是dva来配置,但是发现这样与flask结合的话需要启动两个服务,作为flask只是作为数据的接口,并没用用到其强大 ...

rto初始化和计算_TCP系列13—重传—3、协议中RTO计算和RTO定时器维护相关推荐

  1. rto初始化和计算_TCP系列15—重传—5、Linux中RTO的计算

    之前我们介绍的都是协议中给出的RTO计算方法,下面我们看一下linux实现中RTO的计算方法.在linux中维护了srtt.mdev.mdev_max.rttvar.rtt_seq几个状态变量用来计算 ...

  2. 视频教程-思科CCNP专题系列13:IP多播协议-思科认证

    思科CCNP专题系列13:IP多播协议 新任帮主,双CCIE(CCIE R&S,CCIE Security):2011年前在国内知名培训机构担任CCIE R&S讲师:因一直秉持知行统一 ...

  3. oracle用case计算分段函数,分段函数在微积分中地计算.PDF

    分段函数在微积分中地计算 2013 年12 月 石家庄理工职业学院学术研究 Dec.2013 第8 卷 第4 期 Academic Research of Shijiazhuang Institute ...

  4. IT-标准化-系列-15.在VPC 2007中构建虚拟网络

    看过太多人使用VPC 看过太多人使用Microsoft (R) Virtual Server 2005 R2 看过太多人使用VMware Workstation 没见过有人你像我这样夸张过! 为构建虚 ...

  5. css中会计算的属性,css3中样式计算属性calc()的使用和总结

    calc的介绍 在css3样式中有一个类似与函数的计算属性calc(),它主要用于指定元素的长度,无论是border.margin.pading.font-size和width等属性都可以使用calc ...

  6. 计算机表格中如何计算数据透视表,Excel中如何在数据透视表中进行计算

    会计工作中离不开excel电子表格软件,它不仅具有数据输入.输出.显示.分类.统计.查询等数据处理的基本功能,还具有强大的数据分析功能与程序执行自动化功能,为会计人员的工作提供了许多便利.数据透视表是 ...

  7. c# getresponsestream返回byte[]_C# 基础知识系列-13 常见类库(三)

    0. 前言 在<C# 基础知识系列- 13 常见类库(二)>中,我们介绍了一下DateTime和TimeSpan这两个结构体的内容,也就是C#中日期时间的简单操作.本篇将介绍Guid和Nu ...

  8. lwip路由实现_TCP超时与重传《LwIP协议栈源码详解——TCP/IP协议的实现》

    在TCP两端交互过程中,数据和确认都有可能丢失.TCP通过在发送时设置一个定时器来解决这种问题.如果当定时器溢出时还没有收到确认,它就重传该数据.对任何TCP协议实现而言,怎样决定超时间隔和如何确定重 ...

  9. Apache Flink 漫谈系列(13) - Table API 概述

    什么是Table API 在<Apache Flink 漫谈系列(08) - SQL概览>中我们概要的向大家介绍了什么是好SQL,SQL和Table API是Apache Flink中的同 ...

最新文章

  1. 使用Pyhthon,OpenCV和ZBar构建移动的条码扫描器
  2. java实现qq_java实现的类似qq聊天系统
  3. 【数据分析】数据分析基础:SQL重要知识点梳理!
  4. 堆载预压弹性变形怎样计算公式_一种风洞洞体堆载预压变形测量工艺的制作方法...
  5. handler 与message的一些理解
  6. C++多线程 - 无锁编程
  7. 百度ai开放平台体验
  8. CorelDRAW2020下载使用教程详解
  9. 看到一些关于前端的书籍或者好的网站推荐
  10. strcpy函数在c语言的作用是什么,strcpy函数的作用是什么呀?
  11. 使用DNSLog进行盲打
  12. 【C#基础】输入一个字符,判定它是什么类型的字符(大写字母,小写字母,数字或者其它字符)
  13. JAVA JDK8的介绍下载和安装(附网盘地址)
  14. EBS 12.2 开启JWS
  15. java计算机毕业设计-数字相册管理系统-源程序+mysql+系统+lw文档+远程调试
  16. 抗疫行动题材网页设计 大学生最美逆行者感动人物网页代码 众志成城万众一心抗击疫情HTML网页设计
  17. 精美好用的思维导图插件,无缝对接各种前端框架,快来围观吧
  18. UE4光源、体积雾、IES
  19. 捕鱼达人小游戏——Java实现
  20. Matlab在光学中的应用举例 (一)(理想情况下的双缝干涉)

热门文章

  1. c语言程序设计课件第二章,c语言程序设计课件张元国 ISBN9787566300386 PPT第二章数据类型 运算符与表达式...
  2. mysql+if+x+mod+2_Windows 下 MantisBT 2.X + Apache 2.4 + PHP 7 + MySQL 5.7 的环境配置
  3. 新手上路之django项目开发(二)-----引入静态文件
  4. c语言中的所有代码大全,C语言库函数代码大全
  5. step7db块寻址_step7中的难点:间接寻址示例,中文详细注释。
  6. 【 jquery 】常用
  7. 游戏、脑洞大开1(密码简单破译)
  8. vue跨域解决及打包
  9. 算法初步——two pointers
  10. java学习笔记总略