拥塞控制:

发送端主动控制cwnd,有慢启动(从cwnd初始为1开始启动,指数启动),拥塞避免(到达ssthresh后,为了避免拥塞开始尝试线性增长),快重传(接收方每收到一个报文段都要回复一个当前最大连续位置的确认,发送方只要一连收到三个重复确认就知道接收方丢包了,快速重传丢包的报文,并TCP马上把拥塞窗口 cwnd 减小到1),快恢复(直接从ssthresh线性增长)。

如果网络上的延时突然增加,那么TCP对这个事作出的应对只有重传数据,但是重传会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大。

试想一下,如果一个网络内有成千上万的TCP连接都这么行事,那么马上就会形成“网络风暴”,TCP这个协议就会拖垮整个网络。所以TCP不能忽略网络上发生的事情,而无脑地一个劲地重发数据,对网络造成更大的伤害。对此TCP的设计理念是:TCP不是一个自私的协议,当拥塞发生的时候,要做自我牺牲。就像交通阻塞一样,每个车都应该把路让出来,而不要再去抢路了。

慢启动

只有在TCP连接建立和网络出现超时时才使用。每经过一个传输轮次,拥塞窗口 cwnd 就加倍。一个传输轮次所经历的时间其实就是往返时间RTT。

不过“传输轮次”更加强调:把拥塞窗口cwnd所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。

另外,慢开始的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,使得发送方在开始时只发送一个报文段(目的是试探一下网络的拥塞情况),然后再逐渐增大cwnd。

为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量(如何设置ssthresh)。

慢开始门限ssthresh的用法如下:

  • 当 cwnd < ssthresh 时,使用上述的慢开始算法。
  • 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
  • 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。

拥塞避免算法

让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。

这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。

无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法

这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。

  1. 当TCP连接进行初始化时,把拥塞窗口cwnd置为1。前面已说过,为了便于理解,图中的窗口单位不使用字节而使用报文段的个数。慢开始门限的初始值设置为16个报文段,即 cwnd = 16 。
  2. 在执行慢开始算法时,拥塞窗口 cwnd 的初始值为1。以后发送方每收到一个对新报文段的确认ACK,就把拥塞窗口值另1,然后开始下一轮的传输(图中横坐标为传输轮次)。因此拥塞窗口cwnd随着传输轮次按指数规律增长。当拥塞窗口cwnd增长到慢开始门限值ssthresh时(即当cwnd=16时),就改为执行拥塞控制算法,拥塞窗口按线性规律增长。
  3. 假定拥塞窗口的数值增长到24时,网络出现超时(这很可能就是网络发生拥塞了)。更新后的ssthresh值变为12(即变为出现超时时的拥塞窗口数值24的一半),拥塞窗口再重新设置为1,并执行慢开始算法。当cwnd=ssthresh=12时改为执行拥塞避免算法,拥塞窗口按线性规律增长,每经过一个往返时间增加一个MSS的大小。

强调:“拥塞避免”并非指完全能够避免了拥塞

利用以上的措施要完全避免网络拥塞还是不可能的。“拥塞避免”是说在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。

如果发送方设置的超时计时器时限已到但还没有收到确认,那么很可能是网络出现了拥塞,致使报文段在网络中的某处被丢弃。

这时,TCP马上把拥塞窗口 cwnd 减小到1,并执行慢开始算法,同时把慢开始门限值ssthresh减半。这是不使用快重传的情况。

快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时才进行捎带确认

接收方收到了M1和M2后都分别发出了确认。现在假定接收方没有收到M3但接着收到了M4。显然,接收方不能确认M4,因为M4是收到的失序报文段。

根据可靠传输原理,接收方可以什么都不做,也可以在适当时机发送一次对M2的确认。

按照快重传算法的规定,接收方应及时发送对M2的重复确认,这样做可以让发送方及早知道报文段M3没有到达接收方。

发送方接着发送了M5和M6。接收方收到这两个报文后,也还要再次发出对M2的重复确认。

这样,发送方共收到了接收方的四个对M2的确认,其中后三个都是重复确认。

快重传算法还规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段M3,而不必继续等待M3设置的重传计时器到期

由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高约20%。


与快重传配合使用的还有快恢复算法,其过程有以下两个要点:

  1. 当发送方连续收到三个重复确认,就执行“乘法减小”算法,把慢启动门限ssthresh减半。这是为了预防网络发生拥塞。请注意:接下去不执行慢开始算法。
  2. 由于发送方现在认为网络很可能没有发生拥塞,因此与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。

上图给出了快重传和快恢复的示意图,并标明了“TCP Reno版本”。区别:新的 TCP Reno 版本在快重传之后采用快恢复算法而不是采用慢开始算法。

发送方窗口的上限值 = Min [ rwnd, cwnd ]

  • 当rwnd < cwnd 时,是接收方的接收能力限制发送方窗口的最大值。
  • 当cwnd < rwnd 时,则是网络的拥塞限制发送方窗口的最大值。

tcp拥塞控制_面试必备TCP(四):拥塞控制相关推荐

  1. tcp报文格式_面试必备TCP(一):三次握手

    TCP大家都知道是什么东西,这个协议的具体报文格式如下: 标志位 URG:指示报文中有紧急数据,应尽快传送(相当于高优先级的数据). PSH:为1表示是带有push标志的数据,指示接收方在接收到该报文 ...

  2. tcp 协议中发送窗口的大小应该是_面试必备--TCP协议中的窗口机制滑动窗口详解...

    窗口机制分类 在TCP协议当中窗口机制分为两种: 1.固定的窗口大小 2.滑动窗口 固定窗口存在的问题 我们假设这个固定窗口的大小为1,也就是每次只能发送一个数据,只有接收方对这个数据进行了确认后才能 ...

  3. tcp滑动窗口_面试必备TCP(三):滑动窗口

    之前说过TCP协议头部的组成,不清楚可以点击这里,TCP滑动窗口技术通过动态改变窗口大小来调节两台主机间数据传输. 每个TCP/IP主机支持全双工数据传输,因此TCP有两个滑动窗口:一个用于接收数据, ...

  4. 反向代理post参数怎么传输_面试必备:GET和POST的区别详细解说

    点击右上方红色按钮关注"web秀",让你真正秀起来 前言 最近一些小伙伴面试都会被问到 get 和 post 的区别,很多都只能简单的说几点,今天我们就来把弄的明明白白,彻彻底底. ...

  5. get请求可以传body吗_面试必备:GET和POST的区别详细解说

    点击右上方红色按钮关注"web秀",让你真正秀起来 前言 最近一些小伙伴面试都会被问到 get 和 post 的区别,很多都只能简单的说几点,今天我们就来把弄的明明白白,彻彻底底. ...

  6. 游戏必备组件有哪些_面试必备:2019Vue经典面试题总结(含答案)

    点击右上方红色按钮关注"web秀",让你真正秀起来 面试必备:2019Vue经典面试题总结(含答案) 一.什么是MVVM? MVVM是Model-View-ViewModel的缩写 ...

  7. mysql面试吗hi提_面试必备的10道MySQL题

    MySQL 事务,是我们去面试中高级开发经常会被问到的问题,很多人虽然经常使用 MySQL,SQL 语句也写得很溜,但是面试的时候,被问到这些问题,总是不知从何说起.下面我们先来了解一下什么是 MyS ...

  8. 怎么用Python写出随时间变化的字_面试必备 | 带你彻底搞懂 Python 生成器

    文章转载地址:面试必备 | 带你彻底搞懂 Python 生成器. 写在之前 Python 的高级语言特性一直是我们学习 Python 的一个难点,大部分人并没有做到熟练的掌握,甚至去学习它都感觉很困难 ...

  9. 面试必备TCP三次握手

    目录 概念 TCP三次握手 概念 在进入本篇文章正题之前,需要先了解一下关于TCP连接过程中使用的关键字含义. 序列号seq:标记数据段的顺序. TCP把连接中发送的所有数据字节都编上一个序号,第一个 ...

最新文章

  1. 使用npm打包后生成的package.json中重要字段含义
  2. 《机器人操作系统ROS原理与应用》——1.1 宏观
  3. python是高级动态编程语言-python是一种跨平台、开源、免费的高级动态编程语言,对么...
  4. synchronized不能锁静态变量_肝了一下午的 Synchronized 解析!
  5. opencv 通过网络连接工业相机_Raspberry Pi上的OpenVINO,OpenCV和Movidius NCS
  6. Distributed Representations of Sentences and Documents
  7. 电脑如何连接蓝牙音箱_蓝牙音箱如何办理SRRC认证
  8. 如何解决Ubuntu桥接模式无法联网
  9. 【CentOS】Tomcat的安装
  10. EulerOS简介--openEuler
  11. 盘点:视频监控行业的潜在商机
  12. 200 OK (from cache) 与 304 Not Modified
  13. sql语句用法的一部分整理
  14. 宝宝出生前妈妈准备物品清单
  15. 怎么调大计算机浏览器内字体,浏览器字体大小怎么设置,教你浏览器字体大小怎么设置-win7旗舰版...
  16. Unity3d 接入VKSDK登陆和分享 IOS篇
  17. 详解Unity中的粒子系统Particle System (三)
  18. znpc改版前后网址修改办法
  19. 【HDOJ】4768 Flyer_天涯浪子_新浪博客
  20. ORA-20000:ORU-10027:buffer overflow,limit of 10000 bytes错误4

热门文章

  1. 早秋精品电商男装页面\海报设计PSD模板
  2. Ubuntu16.04 配置VNC
  3. KVM Virtual Networking Concepts
  4. Linux负载均衡Linux Virtual Server (lvs) 内核自带的负载均衡器
  5. IO Visor Project Use Cases
  6. PCI Express®Basics Background | PDF
  7. 【HTML+CSS网页设计与布局 从入门到精通】第13章-块元素div和内联元素span格式布局
  8. 《计算机网络》第四章:介质访问控制(The Medium Access Control Sublayer)
  9. Python IDLE换行写,一行写不下,如何换行继续写
  10. python基础其他(二十一)