[Linux][网络][TCP][四][流量控制][拥塞控制]详细讲解

目录

  • 1.流量控制
  • 2.拥塞控制
    • 0.为什么要有拥塞控制,不是有流量控制么?
    • 1.什么是拥塞窗口?和发送窗口有什么关系呢?
    • 2.怎么知道当前网络是否出现了拥塞呢?
    • 3.拥塞控制有哪些算法?
    • 4.慢启动
    • 5.拥塞避免
    • 6.拥塞发生
    • 7.快速恢复


1.流量控制

  • 发送方不能无脑的发数据给接收方,要考虑接收方处理能力

  • 如果一直无脑地发数据给对方,但对方处理不过来,那么就会导致触发重发机制,从而导致网络流量的无端的浪费

  • 为了解决这种现象发生,TCP提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制

  • 假设以下场景:客户端是接收方,服务端是发送方假设接收窗口和发送窗口相同,都为200,假设两个设备在整个传输过程中都保持相同的窗口大小,不受外界影响

  • 根据下图的流量控制,说明下每个过程:

    • 客户端向服务端发送请求数据报文
      • **说明:**本次例子是把服务端作为发送方,所以没有画出服务端的接收窗口
    • 服务端收到请求报文后,发送确认报⽂和80字节的数据,于是可用窗口Usable减少为120字节,同时SND.NXT指针也向右偏移80字节后,指向321,这意味着下次发送数据的时候,序列号是321
    • 客户端收到80字节数据后,于是接收窗口往右移动80字节, RCV.NXT也就指向321,这意味着客户端期望的下⼀个报文的序列号是 321,接着发送确认报⽂给服务端
    • 服务端再次发送了120字节数据,于是可用窗口耗尽为0,服务端无法再继续发送数据
    • 客户端收到120字节的数据后,于是接收窗口往右移动120字节, RCV.NXT也就指向441,接着发送确认报文给服务端
    • 服务端收到对80字节数据的确认报文后, SND.UNA指针往右偏移后指向321,于是可用窗口Usable增大到80
    • 服务端收到对120字节数据的确认报文后, SND.UNA指针往右偏移后指向441,于是可用窗口Usable增大到200
    • 服务端可以继续发送了,于是发送了160字节的数据后, SND.NXT指向601,于是可用窗口Usable减少到40
    • 客户端收到160字节后,接收窗口往右移动了160字节, RCV.NXT也就是指向了601,接着发送确认报文给服务端
    • 服务端收到对160字节数据的确认报文后,发送窗口往右移动了160字节,于是SND.UNA指针偏移了160后指向601,可用窗口Usable也就增大至了200

请添加图片描述

  • 接收端将自己可以接收的缓冲区大小放入TCP首部中的"窗口大小"字段,通过ACK端通知发送端
  • 窗口大小字段越大, 说明网络的吞吐量越高
  • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端
  • 发送端接受到这个窗口之后,就会减慢自己的发送速度
  • 如果接收端缓冲区满了, 就会将窗口置为0,这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段, 使接收端把窗口大小告诉发送端

2.拥塞控制

0.为什么要有拥塞控制,不是有流量控制么?

  • 前面的流量控制是避免「发送方」的数据填满「接收方」的缓存,但是并不知道网络的中发生了什么
  • ⼀般来说,计算机网络都处在⼀个共享的环境,因此也有可能会因为其他主机之间的通信使得网络拥堵
  • 在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时TCP就会重传数据,但是⼀重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包,这个情况就会进入恶性循环被不断地放大
  • 所以,TCP不能忽略网络上发生的事,它被设计成⼀个无私的协议,当网络发送拥塞时,TCP会自我牺牲,降低发送的数据量
  • 于是,就有了拥塞控制,控制的目的就是避免「发送方」的数据填满整个网络
  • 为了在「发送方」调节所要发送数据的量,定义了⼀个叫做「拥塞窗口」的概念

1.什么是拥塞窗口?和发送窗口有什么关系呢?

  • 拥塞窗口cwnd是发送方维护的⼀个的状态变化,它会根据网络的拥塞程度动态变化的
  • 前面提到过发送窗口swnd和接收窗口rwnd是约等于的关系,那么由于加入了拥塞窗口的概念后,此时发送窗口的值是**swnd = min(cwnd, rwnd)**,也就是发送窗口和接收窗口中的最小值
  • 拥塞窗口cwnd变化的规则
    • 只要网络中没有出现拥塞,cwnd就会增大
    • 但网络中出现了拥塞,cwnd就减少

2.怎么知道当前网络是否出现了拥塞呢?

  • 只要「发送方」没有在规定时间内接收到ACK应答报文,也就是发生了超时重传,就会认为网络出现了拥塞

3.拥塞控制有哪些算法?

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

4.慢启动

  • TCP在刚建立连接完成后,首先是有个慢启动的过程,这个慢启动的意思就是⼀点⼀点的提高发送数据包的数量, 如果一上来就发大量的数据,这不就是给网络添堵吗?
  • 慢启动的算法记住⼀个规则就行:当发送⽅每收到⼀个ACK,拥塞窗口cwnd的大小就会加1
  • 这里假定拥塞窗口cwnd和发送窗口swnd相等,下面举个例子:
    • 连接建立完成后,⼀开始初始化cwnd = 1,表示可以传⼀个MSS大小的数据
    • 当收到⼀个ACK确认应答后,cwnd增加1,于是⼀次能够发送2个
    • 当收到2个的ACK确认应答后, cwnd增加2,于是就可以比之前多发2个,所以这⼀次能够发送4个
    • 当这4个的ACK确认到来的时候,每个确认cwnd增加1,4个确认cwnd增加4,于是就可以比之前多发4个,所以这⼀次能够发送8个
    • 可以看出慢启动算法,发包的个数是指数性的增长

请添加图片描述

  • 那慢启动涨到什么时候是个头呢?
  • 有⼀个叫慢启动门限ssthresh(slow start threshold)状态变量
    • cwnd < ssthresh时,使⽤「慢启动算法」
    • cwnd >= ssthresh时,就会使⽤「拥塞避免算法」

5.拥塞避免

  • 前⾯说到,当拥塞窗口cwnd「超过」慢启动门限ssthresh就会进入拥塞避免算法
  • ⼀般来说ssthresh的大小是65535字节
  • 进入拥塞避免算法后,它的规则是:每当收到⼀个 ACK 时,cwnd增加1/cwnd
  • 接上前面的慢启动的例子,现假定ssthresh为8:
    • 当8个ACK应答确认到来时,每个确认增加1/8,8个ACK确认cwnd⼀共增加1,于是下次能够发送9个MSS大小的数据,变成了线性增长
    • 可以发现,拥塞避免算法就是将原本慢启动算法的指数增长变成了线性增长,还是增长阶段,但是增长速度缓慢了⼀些
    • 就这么⼀直增长着后,网络就会慢慢进⼊了拥塞的状况了,于是就会出现丢包现象,这时就需要对丢失的数据包进行重传。当触发了重传机制,也就进入了「拥塞发生算法」
      请添加图片描述

6.拥塞发生

  • 当网络出现拥塞,也就是会发生数据包重传,重传机制主要有两种:

    • 超时重传
    • 快速重传
  • 发生超时重传的拥塞发生算法

    • ssthresh和cwnd的值会发生变化:
      • ssthresh设为cwnd/2
      • cwnd重置为1
    • 接着,就重新开始慢启动,慢启动是会突然减少数据流的
      • ⼀旦「超时重传」,马上回到解放前。但是这种方式太激进了,反应也很强烈,会造成网络卡顿
        请添加图片描述
  • 发生快速重传的拥塞发生算法

    • 还有更好的方式,前⾯讲过「快速重传算法」。当接收⽅发现丢了⼀个中间包的时候,发送三次前⼀个包的ACK,于是发送端就会快速地重传,不必等待超时再重传
    • TCP认为这种情况不严重,因为大部分没丢,只丢了⼀小部分,则ssthresh和cwnd变化如下:
      • cwnd = cwnd/2 ,也就是设置为原来的⼀半
      • ssthresh = cwnd
      • 进⼊快速恢复算法

7.快速恢复

  • 快速重传和快速恢复算法⼀般同时使用,快速恢复算法是认为,你还能收到3个重复ACK说明网络也不那么糟糕,所以没有必要像RTO超时那么强烈
  • 正如前⾯所说,进⼊快速恢复之前, cwnd和ssthresh已被更新了
    • cwnd = cwnd/2 ,也就是设置为原来的⼀半
    • ssthresh = cwnd
  • 然后,进入快速恢复算法如下
    • 拥塞窗口**cwnd = ssthresh + 3**(3的意思是确认有3个数据包被收到了)
    • 重传丢失的数据包
    • 如果再收到重复的ACK,那么cwnd增加1
    • 如果收到新数据的ACK后,把cwnd设置为第⼀步中的ssthresh的值,原因是该ACK确认了新的数据,说明从duplicated ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进⼊拥塞避免状态

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/8017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

劝退计算机?CS再过几年会没落!?

事实上&#xff0c;未来计算机不仅不会没落&#xff0c;国家还会大力发展 只不过大家认为的计算机就是什么Java web&#xff0c;真正的计算机行业是老美那样的&#xff0c;涉及到方方面面&#xff0c;比如&#xff1a; web&#xff0c;图形学&#xff0c;Linux系统开发&#…

2024DCIC海上风电出力预测Top方案 + 光伏发电出力高分方案学习记录

海上风电出力预测 赛题数据 海上风电出力预测的用电数据分为训练组和测试组两大类&#xff0c;主要包括风电场基本信息、气象变量数据和实际功率数据三个部分。风电场基本信息主要是各风电场的装机容量等信息&#xff1b;气象变量数据是从2022年1月到2024年1月份&#xff0c;…

Skywalking数据持久化与自定义链路追踪

学习本篇文章之前首先要了解一下Sky walking的基础知识 分布式链路追踪工具Skywalking详解 一&#xff0c;Sky walking数据持久化 Sky walking提供了es&#xff0c;MySQL等数据持久化方案&#xff0c;默认使用h2基于内存的数据库&#xff0c;重启之后数据即会丢失。 在实际工…

【Git】Git学习-16:git merge,且解决合并冲突

学习视频链接&#xff1a; 【GeekHour】一小时Git教程_哔哩哔哩_bilibili​编辑https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780 1 创建分支dev&#xff0c;并用merge合并master分支&#xff0c;使dev分支合并上master分支中内容为…

【学习笔记】HarmonyOS 4.0 鸿蒙Next 应用开发--安装开发环境

开发前的准备 首先先到官网去下载Devco Studio 这个开发工具&#xff0c;https://developer.harmonyos.com/cn/develop/deveco-studio/#download 提供了WIndows和Mac的开发环境&#xff0c;我自己是Windows的开发环境。 所以下载之后直接点击exe进行安装即可。 如果之前安装过…

Eplan带你做项目——如何实现项目的交付

前言 Eplan作为一款专业的电气工程设计软件&#xff0c;不仅在设计阶段为电气工程师提供了强大的绘图、计算、仿真等功能&#xff0c;还具备丰富的数据管理与交换能力&#xff0c;能够便捷、准确地导出软件设计、生产制造所需的数据&#xff0c;实现电气设计与软件设计、生产制…

反汇编一个ARM64的机器码

文章目录 使用objdump直接阅读ARM64手册使用反汇编网站 有下面一个机器码&#xff1a;0x929ffee9&#xff0c;如何翻译成汇编呢&#xff1f; 下面介绍几种做法&#xff1a; 使用objdump 将这个机器码写到文件中&#xff0c;然后使用objdump去反汇编 创建一个二进制文件 dd…

Golang | Leetcode Golang题解之第67题二进制求和

题目&#xff1a; 题解&#xff1a; func addBinary(a string, b string) string {ans : ""carry : 0lenA, lenB : len(a), len(b)n : max(lenA, lenB)for i : 0; i < n; i {if i < lenA {carry int(a[lenA-i-1] - 0)}if i < lenB {carry int(b[lenB-i-1…

燃料电池发电系统详解

目录 前言 组成结构 系统参数 常见问题 参考资料 前言 见《氢燃料电池技术综述》 见《燃料电池工作原理详解》 组成结构 燃料电池发电系统&#xff0c;由多个子系统和子模块组成&#xff0c;示例如下&#xff1a; 燃料处理系统&#xff08;fuel processing system&#xf…

IOS离线打包uniapp的信息时报错如下的解决方法

IOS离线打包uniapp的信息时报错如下的解决方法 问题描述&#xff1a; Extract app intents metadata 0.1 seconds XExtractAppIntentsMetadata(in target HBuilder from project HBuilder-Hello)cd /Users/whb/space/vpt/vptios/HBuilder-Hello/Applications/Xcode.app/Conte…

什么是电脑监控软件?哪些监控软件好用?

电脑监控软件是一种用于监控和管理计算机系统和数据的工具。它可以对计算机的使用情况进行实时监控&#xff0c;记录用户的操作行为&#xff0c;并及时发出警报&#xff0c;以防止数据泄露、违规操作和其他安全问题的发生。在当今信息时代&#xff0c;保护企业和个人信息安全变…

OpenNJet 应用引擎:在 NGINX 基础上的云原生增强

目录 一、初识OpenNJet二、系统架构三、动手实践1.CentOS 编译环境配置1.1配置yum源&#xff1a;1.2.yum安装软件包1.3.创建符号连接 2.编译代码编译 OpenNJet执行 make 四、基本使用说明1.目录结构概述:2.常用命令: 五、部署 Web 应用程序配置文件修改启动 NJet 六、总结 一、…

【Unity】使用Resources.LoadAll读取文件的顺序问题

最近在做客户的一个项目&#xff0c;其中的一个模块使用到了照片&#xff0c;但是发现了一个很严重的问题。当你在使用Unity的时候&#xff0c;它竟然不按照顺序读取&#xff1f;这个机器人是不是逻辑有问题&#xff1f;如下图&#xff1a; 名字脱敏了哈。。。 照片比较多&…

【小迪安全2023】第61天:服务攻防-中间件安全CVE复现K8sDockeruettyWebsphere

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

编程语言QT、C++、C#、Matlab、SQL Server开发日志总结

目录 引言 正文 1、Qt连接SQL server数据库 2、C#使用chart绘制实时折线图&#xff0c;波形 3、ORACLEXE数据库 4、QT通过ODBC驱动连接Oracle数据库 5、Microsoft SQL Server 2014 安装图解 6、SQL Server 2014应用 7、C/C​​​​​​​ 8、QT…

Kubernetes容器编排简介

1.1 Kubernetes的诞生到应用 Kubernetes的诞生源于对高效管理和部署大规模容器化应用的需求&#xff0c;它由Google基于其内部使用的Borg系统的核心理念而设计&#xff0c;并在2014年开源&#xff0c;迅速吸引了全球开发者和企业的关注。凭借其开放性和灵活性&#xff0c;Kuber…

Vue3:menu导航栏出现多个同一跳转路径的菜单处理

文章目录 需求整理实现思路实现过程 需求整理&#xff0c;实现思路 最近公司想将之前老的项目整理出来&#xff0c;因为这个老项目内容太杂什么页面都往里面塞&#xff0c;导致菜单特别多&#xff0c;公司就像将这个老的项目迁出来&#xff0c;这个旧的项目本来是后端PHP写的。…

【intro】图注意力网络(GAT)

论文阅读 https://arxiv.org/pdf/1710.10903 abstract GAT&#xff0c;作用于图结构数据&#xff0c;采用masked self-attention layers来弥补之前图卷积或类似图卷积方法的缺点。通过堆叠layers&#xff0c;让节点可以添加其邻居的特征&#xff0c;我们就可以给不同的邻居节…

如何更好地使用Kafka? - 事先预防篇

要确保Kafka在使用过程中的稳定性&#xff0c;需要从kafka在业务中的使用周期进行依次保障。主要可以分为&#xff1a;事先预防&#xff08;通过规范的使用、开发&#xff0c;预防问题产生&#xff09;、运行时监控&#xff08;保障集群稳定&#xff0c;出问题能及时发现&#…

Cargo - 构建 rust项目、管理依赖包

文章目录 关于 Cargo构建项目创建工程编译运行buildclean 管理依赖添加依赖updatecheck计时 manual rust 安装可参考&#xff1a;https://blog.csdn.net/lovechris00/article/details/124808034 关于 Cargo Cargo 官方文档 &#xff1a; https://doc.rust-lang.org/cargo/crat…