rwnd(窗口,代表接收端的处理能力)、cwnd(拥塞窗口,从发送端看当前网络整体承载能力)、ssthresh(快速增长切换成慢速增长的界限值)

1.慢启动,是指数增长(对面确认多少个包,就增加多少),并不慢,只是它的起点低,所以慢启动阶段仍需要时间。实际是起点低(1),快增长阶段,每一轮将当前拥塞窗口翻倍。
2.拥塞避免,引入了ssthresh(这个是个变量,初始往往是最大值65536,随后续拥塞发生不断调整),控制慢启动阶段区间是在窗口超过ssthresh之后,就开始线性增长(是让cwnd缓慢的增加而不是如慢启动时加倍的增长,每经历过一次往返时间就使cwnd增加1,而不是加倍,这样使cwnd缓慢的增长,比慢启动要慢的多。 一种通用的方法是对于TCP发送方无论何时到达一个新的确认,就将cwnd增加一个MSS(MSS/cwnd))。 实际是慢速逼近最大值。

3.拥塞状态,RTO超时且还没有得到数据确认,TCP就会对该报文段进行重传。 超时重传的发生就是拥塞状态进入标志。
拥塞状态发生后,1.把ssthresh降低为cwnd值的一半 2.把cwnd重新设置为1 3.重新进入慢启动过程。

4.仅存在慢启动和拥塞避免实际TCP也可以工作,不断在慢启动和拥塞避免之间循环:
慢启动出现拥塞(ssthresh初始值65536,不会达到),重新进入慢启动。
慢启动cwnd超过ssthresh(ssthresh此时是上次丢包是cwnd的一般,可以超过),进入拥塞避免。
拥塞避免出现拥塞,重新进入慢启动。
......

5.虽然慢启动和拥塞避免 配合拥塞状态也能工作,但发生拥塞后慢启动的起点低,耗时仍比较长,所以有必要叠加快速重传机制。

6.TCP利用3个相同的ACK来判定数据包丢失,这个可以认为是拥塞状态2,这个拥塞状态由接收端判定触发,此时RTO并未超时,只是接收端认为收到了很多大于某个序号seqx的包,但是seqx本身却没收到。 此时进行快速重传操作(每收到一个后面的包就会发一个未收到包的ack),快速重传机制实际就是拥塞状态2发生时的一个处理机制,或者说,拥塞状态2直接命名为快速重传2也可以。
拥塞状态2发生后,1.把ssthresh设置为cwnd的一半 2.把cwnd再设置为ssthresh的值(具体实现有些为ssthresh+3) 3.重新进入拥塞避免阶段。

8.有了拥塞状态2和快速重传机制后,拥塞避免就可以再次进入拥塞避免,这种情况下避免慢启动再次经历耗费时间,对网络的短暂波动适应能力强:
出现拥塞1(超时),则进入慢启动。
出现拥塞2(3ACK),则进入拥塞避免。
可以猜想:
在报文发送较少,低速状态时,发送了一个包,后面又没有什么后续报文。倘若该报文被丢了,此时接收端并不会感知到啥,只能依靠拥塞1来检测进入慢启动了。实际此时慢启动也关系不大,因为本身速率较低。
在报文发送较多,高速状态时,发送了一个包,后续还有很多后续报文。倘若该报文丢了,此时接收端可以更快感知到某个报文被丢弃,因为他会发现后续大部分甚至所有报文都到了,唯独缺了这个报文,就正常分析看,那个报文被丢弃可能性很大。 由于接收端此时对于丢包感知更快,主要会依靠拥塞2来检测,调整ssthresh和cwnd之后再次快速重传进入拥塞避免阶段。 这样避免了重新经历慢启动,节约了部分时间,避免了对速率造成更大影响。

9.通过拥塞2进入拥塞避免会经历快速恢复阶段(也有一种提法根本就没有快速恢复阶段,所谓快速恢复只是指出现拥塞2时直接转入拥塞避免的一个处理机制)。
快速恢复的流程:
1.当收到3个重复ACK时,把ssthresh设置为cwnd的一半,把cwnd设置为当前ssthresh的值加3,然后重传丢失的报文段,加3的原因是因为收到3个重复的ACK,表明有3个“老”的数据包离开了网络到达对岸。
2.再收到重复的ACK时,拥塞窗口增加1。
3.当收到新的数据包的ACK时,把cwnd设置为第一步中保存的ssthresh的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。

TCP的拥塞窗口和快速恢复机制的一些备忘及一点想法的更多相关文章

  1. TCP之拥塞窗口原理

    学过网络相关课程的,都知道TCP中,有两个窗口: 滑动窗口(在我们的上一篇文章中有讲),接收方通过通告发送方自己的可以接受缓冲区大小(这个字段越大说明网络吞吐量越高),从而控制发送方的发送速度. 拥塞 ...

  2. 一文带你掌握【TCP拥塞窗口】原理

    ❝ 关注公众号:高性能架构探索.后台回复[资料],可以免费领取 ❞ 学过网络相关课程的,都知道TCP中,有两个窗口: 滑动窗口(在我们的上一篇文章中有讲),接收方通过通告发送方自己的可以接受缓冲区大小 ...

  3. TCP 拥塞窗口原理

    学过网络相关课程的,都知道TCP中,有两个窗口: 滑动窗口(在我们的上一篇文章中有讲),接收方通过通告发送方自己的可以接受缓冲区大小(这个字段越大说明网络吞吐量越高),从而控制发送方的发送速度. 拥塞 ...

  4. tcp协议头窗口,滑动窗口,流控制,拥塞控制关系

    参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...

  5. TCP 滑动窗口和 拥塞窗口

    转http://coolshell.cn/articles/11609.html 滑动窗口 -- 表征发送端和接收端的接收能力 拥塞窗口-- 表征中间设备的传输能力 TCP滑动窗口 需要说明一下,如果 ...

  6. TCP的滑动窗口机制【转】

    原文链接:http://www.cnblogs.com/luoquan/p/4886345.html      TCP这个协议是网络中使用的比较广泛,他是一个面向连接的可靠的传输协议.既然是一个可靠的 ...

  7. tcp 两个重要窗口:滑动窗口 和 拥塞窗口

    一:滑动窗口是接受数据端使用的窗口大小,用来告知发送端接收端的缓存大小,以此可以控制发送端发送数据的大小,从而达到流量控制的目的,对应==>rwnd:接收端窗口(receiver window) ...

  8. TCP/IP详细解释--TCP/IP可靠的原则 推拉窗 拥塞窗口

    TCP和UDP在同一水平---传输层.但TCP和UDP最不一样的地方.TCP它提供了一个可靠的数据传输服务,TCP是面向连接的,那.使用TCP两台主机通过第一通信"拨打电话"这个过 ...

  9. TCP/IP详细说明--滑模、拥塞窗口、慢启动、Negle算法

    TCP的数据流大致能够分为两类,交互数据流与成块的数据流. 交互数据流就是发送控制命令的数据流.比方relogin,telnet.ftp命令等等.成块数据流是用来发送数据的包,网络上大部分的TCP包都 ...

随机推荐

  1. MySQL MHA候选主库选择

    MHA在选择新主库时,会将所有存活的从库分为下面几类: 存活从库数组:挑选所有存活的从库 最新从库数组: 挑选Master_Log_File+Read_Master_Log_Pos最高的从库 优选从库 ...

  2. 浅谈Python设计模式 - 单例模式

    本篇主要介绍一下关于Python的单例模式,即让一个类对象有且只有一个实例化对象. 一.使用__new__方法(基类) 要实现单例模式,即为了让一个类只能实例化一个实例,那么我们可以去想:既然限制创建 ...

  3. golang读写文件之Scan和Fprintf

    1. 标准输入输出 os提供了标准输入输出: Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin") Stdout = NewF ...

  4. SWD烧录/仿真方式

    单片机在烧写/仿真的时候具有一种方式叫做SWD,这种方式只用到两根线SWDIO,SWCLK.一般SWD和JTAG中的JTMS和JTCK共用的.由于线少,所以使用非常方便,但是速率相对较低. 在接线时, ...

  5. Layui外部js修改表格内容

    //测试修改数据的方法! var _tds=$(".layui-table-body.layui-table-main:eq(1) tr:eq(1)").children(); _ ...

  6. idea中自动deployment的步骤

  7. SHA-1算法——(2)

    地址:https://www.alvestrand.no/objectid/1.3.14.3.2.26.html 地址:http://oidref.com/1.3.14.3.2.26 这个值好像是个标 ...

  8. keepalived+nginx+lnmp 网站架构

    <网站架构演变技术研究> 项目实施手册 2019年8月2日 第一章:  实验环境确认 4 1.1-1.系统版本 4 1.1-2.内核参数 4 1.1-3.主机网络参数设置 4 1-1-4 ...

  9. 玩转DNS服务器——Bind服务

    合理的配置DNS的查询方式 实验环境: 虚拟机:VMware® Workstation 15 Pro 均使用NAT连接   网段为192.168.1.0/24 DNS 服务器 ---- Centos ...

  10. 有意义的单词分割——经典dfs题目

    680. 分割字符串 中文 English 给一个字符串,你可以选择在一个字符或两个相邻字符之后拆分字符串,使字符串由仅一个字符或两个字符组成,输出所有可能的结果 样例 样例1 输入: "1 ...