重传机制

TCP 会在以下两种情况发⽣超时重传:

  • 数据包丢失
  • 确认应答丢失

重传超时

重传超时是TCP协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。

RTT 是数据从⽹络⼀端传送到另⼀端所需的时间,也就是包的往返时间。

RTO (Retransmission Timeout 超时重传时间)。

如果超时重发的数据,再次超时的时候,⼜需要重传的时候,TCP 的策略是超时间隔加倍。

超时重传时间 RTO 的值应该略⼤于报⽂往返 RTT 的值:

快速重传

快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。

它不以时间为驱动,⽽是以数据驱动重传。

Seq 2 丢失,于是后面返回都是ACK 2。收到三个ACk 2之后,在定时器到期之前,重传Seq 2。

快速重传的⼯作⽅式是当收到三个相同的 ACK 报⽂时,会在定时器过期之前,重传丢失的报⽂段。

新的问题?

就是重传的时候,是重传之前的⼀个,还是重传所有。于是提出了SACK方法(Selective Acknowledgment 选择性确认)。

这种⽅式需要在 TCP 头部「选项」字段⾥加⼀个 SACK 的东⻄,它可以将缓存的地图发送给发送⽅,这样发送

⽅就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。

如果要⽀持 SACK ,必须双⽅都要⽀持。在 Linux 下,可以通过 net.ipv4.tcp_sack 参数打开这个功能(Linux

2.4 后默认打开)

滑动窗口

由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包,谁也发不了数据,

所以就有了滑动窗口机制来解决此问题。

有了窗⼝,就可以指定窗⼝⼤⼩,窗⼝⼤⼩就是指⽆需等待确认应答,⽽可以继续发送数据的最⼤值。

窗⼝的实现实际上是操作系统开辟的⼀个缓存空间,发送⽅主机在等到确认应答返回之前,必须在缓冲区中保留已

发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。

详细见图示:

TCP 滑动窗⼝⽅案使⽤三个指针来跟踪在四个传输类别中的每⼀个类别中的字节。其中两个指针是绝对指针(指特定的序列号),⼀个是相对指针(需要做偏移)。

接收窗⼝和发送窗⼝的⼤⼩并不是完全相等,接收窗⼝的⼤⼩是约等于发送窗⼝的⼤⼩的。滑动窗⼝的大小也是根据实际情况不断变化的。

流量控制

TCP 提供⼀种机制可以让「发送⽅」根据「接收⽅」的实际接收能⼒控制发送的数据量,这就是所谓的流量控制。

利用上述的滑动窗口与操作系统的缓存结合来控制流量。

大致设计俩个大问题:

  • 滑动窗口怎么逐渐变小
  • 滑动窗口怎么关闭

减小的过程应该遵循:先收缩窗⼝,过段时间再减少缓存,这样就可以避免了丢包情况。

窗口的关闭:窗⼝⼤⼩为 0 时,就会阻⽌发送⽅给接收⽅传递数据,直到窗⼝变为⾮ 0 为⽌,这就是窗⼝关闭。

潜在的危险-死锁

解决很简单-加定时器,TCP 为每个连接设有⼀个持续定时器,只要 TCP 连接⼀⽅收到对⽅的零窗⼝通知,就启动持续计时器。

如果持续计时器超时,就会发送窗⼝探测 ( Window probe ) 报⽂,⽽对⽅在确认这个探测报⽂时,给出⾃⼰现在的接收窗⼝⼤⼩。

拥塞控制

拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象。

这种现象跟公路网中经常所见的交通拥挤一样,当节假日公路网中车辆大量增加时,各种走向的车流相互干扰,使每辆车到达目的地的时间都相对增加(即延迟增加),甚至有时在某段公路上车辆因堵塞而无法开动(即发生局部死锁)。

发送窗⼝ swnd

接收窗⼝ rwnd

拥塞控制主要是四个算法:

  • 慢启动
  • 拥塞避免
  • 拥塞发⽣
  • 快速恢复

慢启动

有⼀个叫慢启动⻔限 ssthresh (slow start threshold)状态变量。

  • 当 cwnd < ssthresh 时,使⽤慢启动算法。
  • 当 cwnd >= ssthresh 时,就会使⽤「拥塞避免算法」。

拥塞避免

拥塞避免是线性增长,当触发了重传机制,也就进⼊了「拥塞发⽣算法」。

拥塞发⽣算法

重传机制主要有两种:

  • 重传超时
  • 快速重传

重传超时:

  • ssthresh 设为 cwnd/2 ,
  • cwnd 重置为 1


快速重传:

  • cwnd = cwnd/2 ,也就是设置为原来的⼀半
  • ssthresh = cwnd

参考

  • 图解网络-HTTP
  • 中国软件测评中心联合网康推出首个《上网行为管理产品评测标准》
  • 罗万明, 林闯, 阎保平. TCP/IP拥塞控制研究[J]. 计算机学报, 2001, 24(1):1-18.
  • 任丰原, 林闯, 刘卫东. IP网络中的拥塞控制[J]. 计算机学报, 2003, 26(9):2-11.
  • 孙利民, 李波, 周新运. 无线传感器网络的拥塞控制技术[J]. 计算机研究与发展, 2008, 45(1):63-72.
  • 汪小帆, 孙金生, 王执铨. 控制理论在Internet拥塞控制中的应用[J]. 控制与决策, 2002, 17(2):129-134.
  • 趣谈⽹络协议专栏.刘超.极客时间
  • Web协议详解与抓包实战专栏.陶辉.极客时间
  • TCP/IP详解 卷1:协议.范建华 译.机械⼯业出版社
  • 图解TCP/IP.⽵下隆史.⼈⺠邮电出版社
  • The TCP/IP Guide.Charles M. Kozierok.
  • TCP那些事(上).陈皓.酷壳博客.https://coolshell.cn/articles/11564.html
  • TCP那些事(下).陈皓.酷壳博客.https://coolshell.cn/articles/11609.html

TCP 重传、滑动窗⼝、流量控制、拥塞控制的更多相关文章

  1. TCP超时重传、滑动窗口、拥塞控制、快重传和快恢复

    TCP超时重传 原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止. 影响超时重传机制协议效率的一个关键参数是重传超时时 ...

  2. tcp窗口滑动以及拥塞控制

    转自:http://blog.chinaunix.net/uid-26275986-id-4109679.html TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥 ...

  3. tcp窗口滑动以及拥塞控制(转)

    转自:http://blog.chinaunix.net/uid-26275986-id-4109679.html TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥 ...

  4. 斐讯面试记录—TCP滑动窗口及拥塞控制

    TCP协议作为一个可靠的面向流的传输协议,其可靠性是由流量控制和滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现. 一.滑动窗口协议 1. “窗口”对应的是一段可以被发送者发送的字节序 ...

  5. 网络编程之tcp窗口滑动以及拥塞控制

    TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现.一.滑动窗口协议     关于这部分自己不晓得怎么叙述才好,因为理解的部 ...

  6. tcp滑动窗口与拥塞控制

    TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现.一.滑动窗口协议     所谓滑动窗口协议,自己理解有两点:1. “窗口 ...

  7. 【转载】tcp窗口滑动以及拥塞控制

    转自:http://blog.chinaunix.net/uid-26275986-id-4109679.html TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥 ...

  8. 计算机网络【七】:可靠传输的实现 (tcp窗口滑动以及拥塞控制)【转】

    转自:http://blog.chinaunix.net/uid-26275986-id-4109679.html TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥 ...

  9. 对TCP重传的进一步认识

    http://blog.sina.com.cn/s/blog_4d276ac901011ee7.html ——TCM项目所得 一.看图说话 1.基于套接字的TCP服务器/客户端程序流程 2.TCP三次 ...

随机推荐

  1. .NET NuGet整理

    分布式缓存框架: Microsoft Velocity:微软自家分布式缓存服务框架. Memcahed:一套分布式的高速缓存系统,目前被许多网站使用以提升网站的访问速度. Redis:是一个高性能的K ...

  2. 无法cin一个string 没有找到接受“std::string”类型的右操作数的运算符(或没有可接受的转换)

    头文件#include<string>不能写成#include<string.h>

  3. Python:读取二进制文件时使用print输出\x

    问题: 有二进制文件,通过open打开和read()读入并输出时,输出为\x十六进制编码,不能正确显示其具体代表的字符 with open(r'C:\Users\Le\Desktop\Test\tki ...

  4. redis数据类型的使用及介绍

    Redis数据类型 1.Sting类型 set命令 设置键值,存在则覆盖,不存在则新建 set key value EX 秒 设置有效时长为秒 nx 如果键不存在则新建,如果存在返回nil xx 只有 ...

  5. jq获取不包含某些属性的元素

    最近写项目,有个功能实现checkbox全选,但是被禁用的checkbox不能选中 点击全选后发现禁用checkbox的也被选中了,不符合需求. 但是想了半天,属性选择器都是判断某个属性值的,没有判断 ...

  6. deepin下安装ESP32的开发环境

    deepin下安装ESP32的开发环境 本文章用于记录在deepin下安装ESP32的开发环境,前几日在CentOS7之下实现过,但CentOS7对于我这个Linux新手太不友好,于是重装deepin ...

  7. MAC VMware配置Kali linux

    一.部署kali虚拟机 1.选择vmaware fusion12,放弃parallels,因为我用的是MAC系统,所以提供的是VMware的mac版本 2.VMware fusion12邀请码: ZF ...

  8. 如何使用DTM将App事件发送到Google Analytics

    本文分享于华为开发者论坛<如何使用DTM将App事件发送到Google Analytics>,可观看视频具体集成指导. 作为一名开发者或App运营人员,实时获取用户在App中的行为数据是日 ...

  9. 题解 P1659 【[国家集训队]拉拉队排练】

    一眼可得PAM 如果没学过PAM的可以看这里:PAM学习小结 我们令PAM上多记录一个信息\(sum\),表示该节点表示串在原串上出现了多少次. 当我们处理完了\(sum\),对于长度\(len\)为 ...

  10. 万字长文---关于PKM收集与整理系统的思考和实践

    PKM闭环中有一个很重要的环节就是信息输入,包括各种信息来源,例如微信公众号.博客.知乎.RSS等等,因此也就诞生了一大堆稍后读软件,如何真正有效的获取输入而不是做一只仓鼠是需要思考的.最近看了< ...