在本篇中我们继续上一篇文章wireshark的示例讲解,上一篇介绍了一个综合示例后,本篇介绍一些简单的示例,在读本篇前建议先把上一篇读完,为了节省篇幅,本篇只针对一些特殊的场景点报文进行讲解,不会像上一篇一样对每个报文都进行讲解并随报文更新相关状态变量的值了。

一、wireshark示例

本篇示例的TCP测试仍然设置初始拥塞窗口为3,并关闭TSO、GSO等功能。同时设置wireshark使其不在info列显示TSopt的信息。

******@Inspiron:~$ sudo ip route add local127.0.0.2 dev lo congctl reno initcwnd 3#请参考本系列destination metric文章
******@Inspiron:~$ ip route show table all | grep 127.0.0.2
local127.0.0.2 dev lo  table local  scope host  initcwnd 3 congctl reno
******@Inspiron:~$ sudo ethtool -K lo tso off gso off  #关闭tso gso以方便观察cwnd变化  
1、慢启动与延迟ACK

client与server端建立连接后,先发送一个请求报文No4,server端则立即回复ACK确认包。server端在与client建立连接后休眠1000ms,然后每隔5ms发送50bytes的数据包,总共发送14次。client端则每收到两个报文的时候回复一个ACK确认包。最终TCP流如下图所示,图中in_flight列是wireshark对于目前还在传输中的数据量的估计,在这种简单场景下wireshark的估计与linux是一致的,可以作为参考

No9-No13:No9报文回复了No6和No7两个报文,server端收到No9报文后,直接更新cwn=cwnd+2=5,此时in_flight=packets_out=1,因此可以额外发出四个新的数据包,即No10-No13。从wireshark中也可以看到发送完No13后in_flight为250,正好是5个数据包的大小。

No14-No18:与No9-No13类似不再重复分析

No19-No22:server端收到No19后,只有150bytes三个数据包等待发送,因此最终只发出了No20-No22三个数据包。

2、慢启动与ABC、stretched ACK、ACK Compression

ABC(Appropriate Byte Count):是指接收端对于接收到的一个TCP报文,分段反馈多个有效的ACK确认包,如果发送端收到每个ACK确认包后都会更新cwnd,那么在慢启动阶段可能会导致cwnd增长异常迅速,而且超过链路的承载能力,最终降低TCP的性能。这种手段也称呼为ABC攻击。

stretched ACK:我们之前介绍延迟ACK时候介绍过,当以SMSS发送报文的时候,协议规定延迟ACK不能超过两个full-sized报文。但是如果接收端收到的ACK确认包中ack number确认了三个或者以上的full-sized的报文的时候,这个ACK就叫做stretched ACK。stretached ACK原因有多种,最常见的就是ACK报文丢失。

ACK compression:由于中间链路的缓存以及和其他TCP连接一起共享缓存等原因,可能会导致ACK报文成堆到达发送端。这种场景我们就称呼为ACK压缩。

对于ACK compression场景,reno拥塞控制就是逐个处理每个ACK报文,这样就会导致拥塞窗口突然增大,发送端突然发出大量的TCP报文,这种突然发出大量数据的行为我们称呼为burst,影响网络平稳。另外一方面ACK compression还会影响RTT估计,之前我们介绍过有些拥塞控制算法基于时延来来估计网络拥塞情况,因此 ACK compresion还会影响这类基于时延的拥塞控制算法的性能。

在这里我们仅演示一下linux慢启动对于ABC和stretched ACK的处理场景,拥塞避免阶段的处理与慢启动类似不在示例,如下图所示我高亮标出了一些ACK报文

No12:可以看到No12相对于No9报文Ack number一共反馈确认了三个数据包,这个就是我们说的stretched ACK。可以看到此处linux对于stretched ACK的处理上,直接更新了cwnd=cwnd+3,然后一共发出了No13-No18六个数据包。

No19-No21:可以看到No19相对于No12,ack number只反馈确认了30bytes的数据,并没有完整反馈No11这个数据包,No20同样也没有完整反馈No11这个数据包,linux在收到这两个ACK报文的时候,则会判断是否完整反馈了之前发出的No11数据包,当发现没有完整反馈No11数据包的时候并不会更新cwnd。直到linux收到No21这个数据包后,发现之前的No11这个数据包已经被完整反馈了,因此更新cwnd=cwnd+1,发出两个数据包。

3、多个数据包RTO超时

在之前的综合示例中我们看到过,一次RTO超时触发重传后,同一个报文的多次RTO超时并不会继续更新ssthresh,而随后的recovery point之前的慢启动重传也不会更新ssthresh。但是在recovery point之前的多个数据包触发的RTO超时则会重新更新ssthresh。一定要记得是不同TCP报文的RTO超时才会更新ssthresh,而linux只有一个RTO定时器。要分清慢启动重传和RTO超时重传的区别。

这个示例与综合示例非常类似,不同点在于这次RTO超时的是Seq为451的报文,而且No43对应的报文发生了两次RTO超时。下面总结一下这个示例相对于综合示例的几个注意点

No35:可以看到这个loss probe报文是个重传包,而之前综合示例中,loss probe报文是一个未发送过的报文,这里一定要分清,No35的重传是TLP超时触发的,而不是RTO超时触发。看不懂的前翻TLP的文章。

No43、No47、No48:No43是一个慢启动重传,并不是RTO超时触发的,因此不会更新ssthresh,而No47则是No43的RTO超时重传,因此会更新ssthresh = max(cwnd/2, 2),实际上在RTO超时发出No47之前,ssthresh=6,cwnd=4,而RTO超时发出No47报文后,则更新ssthresh=2,cwnd=1。No48同样是RTO超时重传,但是No48和No47是同一个数据包的多次连续RTO超时重传因此不会更新ssthresh。另外这里可以看到wireshark估计的in_flight的大小与linux的差异,例如在RTO超时重传No35后,linux计算的in_flight为1,大小实际为50bytes。之前我们已经介绍过多个linux和wireshark对数据包理解上的差异了。

TCP系列38—拥塞控制—1、概述的更多相关文章

  1. TCP系列55—拥塞控制—18、其他拥塞控制算法及相关内容概述

    前面我们演示分析了100+个wireshark TCP实例,拥塞控制部分也介绍常见的拥塞处理场景以及4种拥塞撤销机制,但是我们一直使用的都是reno拥塞控制算法.实际上拥塞控制发展到今天已经有了各种各 ...

  2. TCP系列39—拥塞控制—2、拥塞相关算法及基础知识

    一.拥塞控制的相关算法 早期的TCP协议只有基于窗口的流控(flow control)机制而没有拥塞控制机制,因而易导致网络拥塞.1988年Jacobson针对TCP在网络拥塞控制方面的不足,提出了& ...

  3. TCP系列40—拥塞控制—3、慢启动和拥塞避免概述

    本篇中先介绍一下慢启动和拥塞避免的大概过程,下一篇中将会给出多个linux下reno拥塞控制算法的wireshark示例,并详细解释慢启动和拥塞避免的过程. 一.慢启动(slow start) 一个T ...

  4. TCP系列54—拥塞控制—17、AQM及ECN

    一.概述 ECN的相关内容是在RFC3168中定义的,这里我简单描述一下RFC3168涉及的主要内容. 1.AQM和RED 目前TCP中多数的拥塞控制算法都是通过缓慢增加拥塞窗口直到检测到丢包来进行慢 ...

  5. TCP系列52—拥塞控制—15、前向重传与RACK重传拥塞控制处理对比

    一.概述 这里主要简单分析一个丢包重传并恢复的场景,通过不同的设置让这个相同的场景分别触发RACK重传和前向重传,通过对比说明以下问题: Forward Retransmit可以产生只有重传标记的数据 ...

  6. TCP系列51—拥塞控制—14、TLP、ER与拥塞控制

    一.概述 这里的重点是介绍TLP.ER与拥塞控制并不是介绍TLP和ER本身,因此TLP和ER的详细内容请翻前文. 在TLP与拥塞控制的交互中有几个点需要注意 1.TLP触发的重传后,TCP仍然处于Op ...

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

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

  8. TCP系列47—拥塞控制—10、FACK下的快速恢复与PRR

    一.概述 FACK下的重传我们在之前的重传部分已经进行了介绍,这里简单介绍一下随着FACK提出的拥塞控制算法的改进及随后的进一步改进. 从我们之前介绍的RFC2582和RFC5681中可以看到,快速恢 ...

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

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

随机推荐

  1. JAVA中判断年月日格式是否正确(支持判断闰年的2月份)

    一.先说一下年月日(yyyy-MM-dd)正则表达式: 1.年月日正则表达式:^((19|20)[0-9]{2})-((0?2-((0?[1-9])|([1-2][0-9])))|(0?(1|3|5| ...

  2. 剑指Offer-迭代

    1.大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0) 备注:斐波那契数列指的是这样一个数列从第3项开始,每一项都等于前两项之和. public st ...

  3. 「PHP」设计模式介绍

    引言   最近再看PHP设计模式相关的一些技术文章,网上有关PHP的设计模式范例很少,这里做一些总结仅供参考,不足之处望提出. 参考资料: <大话设计模式>程杰   什么是设计模式   设 ...

  4. 对象转换成JSON字符串

    定义一个Student类: 1 class Student { 2 public $name; 3 public $age; 4 function __construct($name, $age) { ...

  5. php的基础知识(一)

    php(超文本预处理器)定义: php(外文名:php:Hertext Preprocessor,中文名:“超文本预处理器”)是一种通用的开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于 ...

  6. yii学习笔记(1),目录结构和请求过程

    最近找找工作面试,发现很多要求会yii.于是准备学习一个新的框架 先在腾讯课堂找了个视频看了一下,然后去网上现在了“归档文件”(还有一种方式是通过php的包管理工具“composer”安装) 归档文件 ...

  7. 嵌入式GPIO接口及操作(二)

    目标:C语言实现点亮LED灯 首先是main函数,并不特殊,它是被系统调用来执行的,main函数结束后要返回调用main函数的地址处,那么裸机程序,没有操作系统做这些工作,就要自己写调用main函数的 ...

  8. C++函数调用之——值传递、指针传递、引用传递

    1.简介 1.值传递:形参时实参的拷贝,改变函数形参并不影响函数外部的实参,这是最常用的一种传递方式,也是最简单的一种传递方式.只需要传递参数,返回值是return考虑的:使用值传递这种方式,调用函数 ...

  9. MySQL集群-PXC搭建以及使用innobackupex工具进行全局备份和增量备份

    环境:centos7 vm1:10.154.47.236 vm2:10.154.52.189 vm3:10.105.12.50 目的:pxc使用三个节点构建mysql集群,使用innobackupex ...

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

    20145209 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 1.构造方法决定类生成对象的方式 用this将已存在的参数的值指定给此参数. 用new建立新 ...