一、概述

这里的重点是介绍TLP、ER与拥塞控制并不是介绍TLP和ER本身,因此TLP和ER的详细内容请翻前文。

在TLP与拥塞控制的交互中有几个点需要注意

1、TLP触发的重传后,TCP仍然处于Open状态,TLP重传也不会更新lost_out等状态变量,TLP重传发出的是探测报文并不是因为当前确定丢包而重传。

2、TLP与ER/FACK是相互组合的,TLP触发的FACK重传与之前介绍的FACK下快速恢复一致。TLP和ER的耦合更深一些,TLP只能触发延迟ER,而ER定时器超时,延迟ER重传将TCP切换到Recovery状态的时候并不会更新cwnd,但是同样会更新prior_ssthresh=max(ssthresh,3/4*cwnd), ssthresh=max(cwnd/2,2),prior_cwnd=cwnd,prr_delivered=0, prr_out=0, high_seq=snd.nxt,cwnd不变。但是随后切换到Recovery状态后cwnd的更新流程就与之前文章介绍的一致了。

我们还要额外说一下TLP的loss dection,在重传部分介绍TLP的时候,提到过TLP的丢包探测,TLP在发出loss probe报文的时候,是假设当前没有发生拥塞的,即没有丢包,TCP的状态继续停留在Open态。因而TLP需要一种方法来检测是否真的发生了丢包,当检测到真的发生了丢包的时候,进行拥塞窗口的调整。当TLP发出的loss probe报文重传的TCP数据包时候,会记录一个状态变量tlp_high_seq=snd.nxt,tlp_high_seq这个字段在TCP进入Recovery、CWR或者RTO超时场景下都会重置为0。当TLP收到ACK确认包的时候,会按照下面的流程进行loss dection:

1、当tlp_high_seq==0,或者acknumber<tlp_high_seq时候,结束处理,不再执行下面其他步骤。

2、如果这个ACK报文带有DSACK信息,那么说明原始报文和TLP重传报文都到达了对端,更新tlp_high_seq=0,结束处理,不再执行下面其他步骤。

3、如果acknumber>tlp_high_seq,说明原始传输的报文或者TLP重传报文有丢包,因此需要调整拥塞窗口。首先先初始化拥塞窗口削减过程,设置tlp_high_seq=0, high_seq=0, cwnd_cnt=0, prr_delivered=0, prr_out=0, ssthresh=max(cwnd/2,2),临时把TCP的拥塞状态设置为CWR然后进行CWR状态下的拥塞削减结束过程,更新cwnd=ssthresh,最后在根据当前sacked_out等情况决定是切换到Open状态或者是Disorder状态,结束处理,不再执行下面其他步骤。

4、如果这个ACK报文没有传输TCP数据(pure ACK),而且ack number或者SACK块没有确认新数据,也不是窗口更新消息,(这个ACK称呼为TLP dup ACK),说明原始报文和TLP重传报文都到达了对端,更新tlp_high_seq=0。

5、如果上面的条件都不满足,那么TLP结束对这个ACK的处理,等待随后的ACK。

如果不理解上面的这个loss dection流程,那么可以参考之前重传部分TLP的文章或者TLP的官方文档,或者参考下面的示例来理解。

二、wireshark示例

1、TLP&增强ER与拥塞控制

在执行本示例前,如下设置TCP参数

  1. ******@Inspiron:~$sudo ip route add local 127.0.0.2 dev lo congctl reno initcwnd 3  ssthresh lock 20   #参考本系列destination metric文章
  2. ******@Inspiron:~$ sudo ethtool -K lo tso off gso off  #关闭tso gso以方便观察cwnd变化

业务场景:server端与client建立连接后,先休眠1000ms,接着以3ms为间隔连续发送5个数据包,其中No10和No11这两个数据包丢失,以触发loss probe及增前ER,client对于收到的每个数据包都会回复一个ACK确认包,最终TCP的交互如wireshark截图所示。

No1-No13:不解释了,最终收到No13确认包后, ssthresh=20, cwnd=6,cwnd_cnt=0, packets_out=2, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,server端处于Open状态,PTO定时器定时时间大约为100ms。

No14:PTO定时器超时,触发loss probe,重传最后发出的一个数据包(即No11)。注意这里虽然是tcp重传,但是并不会更新lost_out等参数,server端TCP仍然会停留在Open状态, ssthresh=20, cwnd=6,cwnd_cnt=0, packets_out=2, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0。重传后设置RTO定时器,RTO超时时间大约为250ms。

No15:No15是client收到No14数据包后回复的ACK确认包,通过SACK选项确认了No14报文,更新sacked_out=1,fackets_out=2。此时packets_out=2<4,且缓存中没有待发送数据,因此满足触发延迟ER的条件,取消RTO定时器并启动ER定时器,定时时间为RTT/4,大约为13ms。接着因为收到dup ACK,server端TCP从Open状态切换到Disorder状态。

No16:ER定时器超时,重传No10报文,server端TCP从Disorder状态切换到Recovery状态,注意这里ER重传触发TCP进入Disorder状态的时候,只会更新prior_ssthresh=max(ssthresh,3/4*cwnd)=20, ssthresh=max(cwnd/2,2)=3, prior_cwnd=cwnd=6,prr_delivered=0, prr_out=0, high_seq=251,而cwnd在触发ER重传的时候并不会更新,这是与之前介绍的FACK、SACK、SACK关闭场景下的触发的快速重传的重要区别。除了ER重传进入Recovery状态时候初始化与之前介绍的快速重传不一样外,在进入Recovery状态后的各种处理都是一样的了。

No17:server端收到对应No16的ACK确认包,同时这个确认包的ack number=251=high_seq,此时SACK处于打开的状态,因此更新cwnd=ssthresh=3,TCP从Recovery状态切换到Open状态,接着进行reno的拥塞避免过程,更新cwnd_cnt=2。

2、TLP Loss Detection与拥塞控制

在执行本示例前,如下设置TCP参数

  1. ******@Inspiron:~$sudo ip route add local 127.0.0.2 dev lo congctl reno initcwnd 3  ssthresh lock 20   #参考本系列destination metric文章
  2. ******@Inspiron:~$ sudo ethtool -K lo tso off gso off  #关闭tso gso以方便观察cwnd变化

业务场景:server端与client建立连接后,先休眠1000ms,接着以3ms为间隔连续发送5个数据包,其中No11数据包丢失,以触发loss probe,接着休眠353ms写入50bytes的数据。client对于收到的每个数据包都会回复一个ACK确认包,最终TCP的交互如wireshark截图所示。

No1-No14:这个过程不解释了,注意No6-No14报文一直在重设TLP定时器,server在收到No14报文后,发现当前packets_out=1,因此更新PTO =max(2*SRTT, 1.5*SRTT+WCDelAckT)≈275,PTO=min(PTO, RTO)≈250,因此No14后设置PTO定时器定时时间约为250ms, ssthresh=20, cwnd=7,cwnd_cnt=0, packets_out=1, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,server端TCP处于Open状态。

No15:PTO定时器超时后触发尾包重传,即No15,TLP超时触发的尾包重传是假设当前没有发生网络拥塞的,因此并不会将TCP切换到Loss状态或者Recovery状态,也不会更新lost_out字段,发出No15后, ssthresh=20, cwnd=7,cwnd_cnt=0, packets_out=1, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,tlp_high_seq=251,server端TCP处于Open状态。

No16:server端休眠唤醒后,进行一次write操作,写入50bytes的数据,更新packets_out=2。

No17:client收到No15后,回复一个确认包,server收到No17后首先更新packets_out=1。这个确认包的acknumber=251,根据概述里面的流程描述,TLP并不会处理这个ACK确认包,而是会等待下一个ACK。接着进行reno的慢启动处理,更新cwnd=8。最终 ssthresh=20, cwnd=8,cwnd_cnt=0, packets_out=1, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,tlp_high_seq=251,server端TCP处于Open状态

No18:client收到No16后回复No18,server端收到No18后更新packets_out=0,TLP收到这个ACK报文后,发现满足概述里面ACK处理流程的第3步骤,因此更新tlp_high_seq=0,ssthresh=max(cwnd/2,2)=4,cwnd=ssthresh=4。最终ssthresh=4, cwnd=4,cwnd_cnt=0, packets_out=0, sacked_out=0,  lost_out=0, retrans_out=0, fackets_out=0,tlp_high_seq=0,server端TCP处于Open状态。

这里假如No11没有丢包,而只是RTT时延突然变大导致server端同样触发TLP流程,那么server端应该会首先收到一个类似No17的报文(client对No11的确认包),TLP不处理这个ACK报文,然后会在收到一个TLP dup ACK(client对于No15的确认包),TLP按照概述里面的第4步更新tlp_high_seq=0,因而也就不会触发ssthresh和cwnd的削减过程。

补充说明:

1、延迟ER处理tcp_resume_early_retransmit

2、TLP ACK处理tcp_process_tlp_ack

TCP系列51—拥塞控制—14、TLP、ER与拥塞控制的更多相关文章

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

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

  2. TCP系列46—拥塞控制—9、SACK下的快速恢复与Limited transmit

    一.概述 1.SACK下的特殊处理过程 SACK下的拥塞控制处理是linux中拥塞控制的实现依据,再次强调一遍RFC6675的重要性,linux中拥塞控制主体框架的实现是与RFC6675一致的,所以如 ...

  3. TCP系列20—重传—10、早期重传(ER)

    一.介绍 在前面介绍thin stream时候我们介绍过有两种场景下可能不会产生足够的dup ACK来触发快速重传,一种是游戏类响应交互式tcp传输,另外一种是传输受到拥塞控制的限制,只能发送少量TC ...

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

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

  5. 【图解】你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了

    每日一句英语学习,每天进步一点点: 前言 前一篇「硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题」得到了很多读者的认可,在此特别感谢你们的认可,大家都暖暖的. 来了,今 ...

  6. 【Lucene3.6.2入门系列】第14节_SolrJ操作索引和搜索文档以及整合中文分词

    package com.jadyer.solrj; import java.util.ArrayList; import java.util.List; import org.apache.solr. ...

  7. 深入浅出图解【计算机网络】 之 【TCP可靠传输的实现2: 超时重传+拥塞控制】

    [前言]上一篇文章介绍了关于TCP的基础知识,以及建立(释放)连接和滑动窗口的概念. 本篇文章将延续上一篇的思路,继续介绍TCP实现可靠传输的机制. 超时重传 上一篇文章里介绍过TCP采用停止等待协议 ...

  8. TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接

    一.TCP连接的ISN         之前我们说过初始建立TCP连接的时候的系列号(ISN)是随机选择的,那么这个系列号为什么不采用一个固定的值呢?主要有两方面的原因 防止同一个连接的不同实例(di ...

  9. TCP系列48—拥塞控制—11、FRTO拥塞撤销

    一.概述 FRTO虚假超时重传检测我们之前重传章节的文章已经介绍过了,这里不再重复介绍,针对后面的示例在说明两点 1.FRTO只能用于虚假超时重传的探测,不能用于虚假快速重传的探测. 2.延迟ER重传 ...

随机推荐

  1. STM32F4XX中断方式通过IO模拟I2C总线Master模式

    STM32的I2C硬核为了规避NXP的知识产权,使得I2C用起来经常出问题,因此ST公司推出了CPAL库,CPAL库在中断方式工作下仅支持无子地址 的器件,无法做到中断方式完成读写大部分I2C器件.同 ...

  2. 基于STM32的简易数码相册

    原理:在板子上插入SD卡,并使用FATFS文件系统来循环读取并显示SD卡内的指定目录内的所有BMP图片. 这是显示效果(能上传视频的话就能看到循环显示效果): 因为图片显示函数显示的是24位BMP图片 ...

  3. Python学习 :网络通信要素

    网络通信 OSI 模型 - 定义了计算机互联的标准,是设计和描述计算机网络通信的基本框架 - 把网络通信的工作分为7层,分别是物理层.链路层(数据网络层).网络层.传输层.会话层.表示层和应用层 网络 ...

  4. Makefile:(实验)多个目标匹配时会采用最完整匹配的目标

    结论源自实验测试,如果有疏漏希望指出 当Makefile中存在多个匹配的目标时,Makefile会采用哪个匹配的目标呢? 测试的Makefile如下: .PHONY: all clean quick_ ...

  5. nw

    https://github.com/nwjs/nw.js/wiki/List-of-apps-and-companies-using-nw.js

  6. 20155217 2016-2017-2 《Java程序设计》第10周学习总结

    20155217 2016-2017-2 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据. 程序员所作的事情 ...

  7. 20155227 2016-2017-2 《Java程序设计》第六周学习总结

    20155227 2016-2017-2 <Java程序设计>第六周学习总结 教材学习内容总结 InputStream与OutputStream 串流设计 流(Stream)是对「输入输出 ...

  8. 《图说VR入门》——googleVR 他山之玉

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/53125482 作者:car ...

  9. P2P平台投宝金融跑路?为什么我没有中雷!

    编者按:市场有风险,投资需谨慎.最近,安徽合肥P2P平台"投保金融"跑路倒闭了. 今天(2016年11月8日)下午,在朋友圈看到一个分享,投宝金融跑路了,新闻媒体已经传开了. 这个 ...

  10. Unity3D使用NGUI实现简单背包功能

    前话 在许多类型游戏中我们经常会使用到背包,利用背包来设置相应角色属性,多了背包也会让游戏增色拓展不少. 那在Unity3D游戏开发中该如何编写背包系统呢?因为有高人开发了NGUI插件,因此我们进行简 ...