一、概述

这里的重点是介绍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

来自为知笔记(Wiz)

转载于:https://www.cnblogs.com/lshs/p/6038805.html

TCP系列51—拥塞控制—14、TLP、ER与拥塞控制相关推荐

  1. 30 张图解: 面试必问的 TCP 重传、滑动窗口、流量控制、拥塞控制

    前言 前一篇「硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题」得到了很多读者的认可,在此特别感谢你们的认可,大家都暖暖的. 来了,今天又来图解 TCP 了,小林可能会迟 ...

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

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

  3. java tcp权限控制_「图解」TCP重传、滑动窗口、流量控制、拥塞控制

    前言 前一篇35 张图解被问千百遍的 TCP 三次握手和四次挥手面试题得到了很多读者的认可,在此特别感谢你们的认可,大家都暖暖的. 来了,今天又来图解 TCP 了,小林可能会迟到,但不会缺席. 迟到的 ...

  4. tcp下载窗口太小的问题_图解 TCP 重传、滑动窗口、流量控制、拥塞控制

    相信大家都知道 TCP 是一个可靠传输的协议,那如何它是如何保证可靠的呢? 为了实现可靠性传输,需要考虑很多事情,例如数据的破坏.丢包.重复以及分片顺序混乱等问题.如不能解决这些问题,也就无从谈起可靠 ...

  5. TCP 重传、滑动窗口、流量控制、拥塞控制★★★

    正文 相信大家都知道 TCP 是一个可靠传输的协议,那它是如何保证可靠的呢? 为了实现可靠性传输,需要考虑很多事情,例如数据的破坏.丢包.重复以及分片顺序混乱等问题.如不能解决这些问题,也就无从谈起可 ...

  6. DotNetty 实现 Modbus TCP 系列 (三) Codecs Handler

    DotNetty 实现 Modbus TCP 系列 (一) 报文类 DotNetty 实现 Modbus TCP 系列 (二) ModbusFunction 类图及继承举例 DotNetty 作为一个 ...

  7. DotNetty 实现 Modbus TCP 系列 (二) ModbusFunction 类图及继承举例

    DotNetty 实现 Modbus TCP 系列 (一) 报文类 ModbusFunction 类图如下: 如前文所述,所有请求/相应的 PDU 均继承自 ModbusFunction,其子类传入对 ...

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

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

  9. TCP基于窗口的端到端的拥塞控制机制

    1988年Van Jacobson指出了TCP在控制网络拥塞方面的不足,并提出了"慢启动"(Slow Start)."拥塞避免"(Congestion Avoi ...

最新文章

  1. android的权限问题
  2. 使用访问控制列表预防IP地址欺骗(IP Address Spoofing Prevention with ACLs)
  3. 基础的java增删改查,Java基础系列(基础):Java使用Cookie增删改查操作!
  4. 浙江大学计算机基础上机实验答案,2015年浙江大学远程教育计算机基础知识题及参考答案(2)...
  5. 远程桌面与远程协助的区别mstsc /console
  6. CHIP ID was not passed on from the tile; contact your system administrator
  7. IDEA 中tomcat上面有个x 而且找不到配置tomcat的选项
  8. 方法:查询MongoDB数据库中最新一条数据(JAVA)
  9. 解决 maps to localhost, but this does not map back to the address
  10. java 各种数据库连接_JAVA连接各种数据库
  11. python 获取运行文件的路径
  12. 关于JS特效的兼容问题。
  13. 【数据结构笔记11】二叉搜索树,动态查找,删除操作
  14. HTTP上传大文件的注意点
  15. JN5169 Bootload 烧录过程和DIY烧录程序(一)
  16. [JPA错误]javax.persistence.EntityNotFoundException: Unable to find xxx
  17. Android使用高德地图api实现基础定位
  18. 微信群、朋友圈和订阅号的流量到底有什么差异?
  19. 【Spring Boot】使用mockMvc模拟请求以及遇到的问题
  20. echarts中y轴设置刻度_ECharts中y坐标轴刻度的属性

热门文章

  1. python `__str__`
  2. python color属性_模块“cv2.cv2”没有“COLOR”属性“BGR2GREY”
  3. Matlab标准语音库 Timit Database
  4. 42张PPT揭秘字节跳动人力资源体系(推荐收藏)
  5. 虚拟化小白对VMcpu分配的理解
  6. java中图片与像素矩阵转换,java - Java中具有矩阵乘法的图片转换不起作用 - 堆栈内存溢出...
  7. 台式计算机一般多大功率,台式电脑功率一般多大 台式机功率有多少【详细介绍】...
  8. 无人车首例阵亡事件,AI教育春江水暖
  9. HDFS基本原理及数据存取实战
  10. U3d中实现A*寻路,附源文件