当前位置: 首页 > news >正文

【网路通信基础与实践番外二】TCP协议的流量控制和拥塞控制以及二者区别和例题

TCP协议是端对端的协议,因此在数据进行传输的过程受发送方,数据通道,接收方三方状态的影响。我们用水龙头来比喻数据发送方,水管来比喻数据通道,水桶来表示数据接收方。

图(a)表示水桶太小,来不及接受注入水桶的水,而传输网络保持畅通,这时只能请求管水龙头的人把水龙头拧小一些,以减缓放水的速率,这就相当于是流量控制。

图(b)表示虽然水桶足够大,但是管道中有很狭窄的地方,使得管道不通畅,水流被堵塞,这种情况反馈到管水龙头的人那里,请求把水龙头拧小一些,以减缓放水的速率,为的减缓水管的堵塞状态,这就相当于是拥塞控制。

一、流量控制

在每一个TCP连接的一侧主机都会有一个socket缓冲区,缓冲区会为每个连接设置接收缓存和发送缓存,当TCP建立连接后,从应用程序产生的数据就会到达接收方的接收缓冲区中,接收方的应用程序并不一定会马上读取缓冲区的数据,他需要等待操作系统分配时间片。如果此时发送方的应用程序产生数据过快,而接收方读取接收缓冲区的数据相对较慢的话,那么接受方中缓冲区的数据就会溢出。

TCP的流量控制本质上是一个速度匹配服务,匹配发送方发送率和接收方的接受速率,避免出现发送方发送过快而接收方接受过慢的情况,从而消除缓冲区溢出的情况。

TCP通过使用一个接收窗口(receive window)来提供流量控制。在TCP报文结构中首部有一个接收窗口变字段,接收端通过向发送端发送报文,报文中就包含了接受窗口变量,接收窗口会给发送方一个指示到底还有多少可用的缓存空间。发送方发送不能超过这个限额的数据,这样发送方会根据接收端的实际接受能力来控制发送到数据量。

那么知道了接收窗口(receive window)之后,它具体是如何用来流量控制呢?

如上图所示,发送端主机会定期向接收端主机发送一个窗口探测包,这个包用于探测接收端主机是否能够接收数据,当接收端的缓冲区一旦面临数据溢出的风险,窗口大小的值也随之被设置为一个更小的值通知到发送端,从而控制数据发送量。

开始的窗口大小设置为3000,发送方每次发送报文长度为1000的报文,当接收端B收到2000-2999的报文之后缓冲区已满,不得不暂停接收数据。然后主机A发送窗口探测包,窗口探测包是一个非常小的字节,然后主机B更新缓冲区接受窗口大小并发送窗口更新通知到主机A,然后主机A再继续发送报文段。在上面的发送过程中,窗口更新通知可能会丢失,一旦丢失发送端就不会发送数据,所以窗口探测包会随机发送,以避免这种情况发生。

二、拥塞控制

有了TCP窗口控制机制之后,使得计算机网络中两个主机之间不再是以单个数据段的形式发送了,而是能够连续发送大量的数据包。但是发送大数据包的时候也面临着例如网络负载、网络拥堵的问题。TCP为了防止这类问题的出现,使用了拥塞控制机制,会在面临网络拥塞时遏制发送方的数据发送。

拥塞控制主要有两种方法:

端到端的控制:因为网络层没有为运输层拥塞控制提供显示支持,IP层不会向端系统提供有关网络拥塞的反馈信息。如果超时或者三次冗余确认就被认为是网络拥塞,TCP会减小窗口的大小,或者增加往返时延来避免。

网络辅助的拥塞控制:在网络辅助的拥塞控制中,路由器会向发送方提供有关网络中拥塞状态的反馈。这种反馈信息就是一个比特信息,它指示链路中的拥塞情况。

TCP发送方通过超时或者三个冗余ACK来感知网络拥塞,通过拥塞窗口cwnd来限制TCP在接收到ACK之前可以发送到网络的数据量。

一般来说,发送方未确认的数据量不得超过cwnd和rwnd的最小值,即:

LastByteSent - LastByteAcked <= min(cwnd, rwnd)

由于每个数据包往返时间为诶RTT,我们假设接受空间有足够的缓存用来接收数据,即只考虑cwnd,那么发送方的发送速率为cwnd/RTT 字节/秒,通过调节cwnd,发送方就可以调节它向连接发送数据的速率。

TCP进行拥塞控制的算法有四种:慢开始(slow start),拥塞避免(congestion avoidance),快重传(fast retransmit)和快恢复(fast recovery)

(1)慢开始

当一条TCP开始建立连接时,cwnd的值会初始化一个MSS的较小值。在慢启动的方式中,cwnd的值会初始化为一个MSS,并且每次传输报文确认后会增加一个MSS,cwnd的值会变成2个MSS,这两个报文段都传输成功后每个报文段加一,会变成4个MSS,以此类推,每成功一次cwnd的值会翻倍。

(2)拥塞避免

为了防止cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。当cwnd > ssthresh时停用慢开始算法而改用拥塞避免算法,具体表现为加法线性规律缓慢增大。

(3)快重传和快恢复

有时候个别报文段就会在网络中意外丢失,但是实际上网络并未发生拥塞。如果发送方迟迟收不到确认,就会产生超时,并误认为网络发生了拥塞。这就导致发送方错误地开启慢启动模式,又将拥塞窗口设置为1,不必要的降低了传输效率。

快重传算法规定发送方只要一连收到3个重复确认,就可以知道现在并未出现网络拥塞,而只是接收方少收到一个报文段,并对此报文段进行重传。

在3-ACK点处发送方知道现在只是丢失了个别的报文段,于是不启动慢开始,而是执行快恢复算法。这时发送方第二次调整门限值,使ssthresh = cwnd / 2,开始执行拥塞避免算法。

 

三、流量控制和拥塞控制的区别

四、例题

 超时之后ssthresh = cwnd / 2 = 16 / 2 =8,之后执行慢开始,第一个RTT是2,第二次RTT是4,第三个RTT是8,此时cwnd = ssthresh = 8,执行拥塞避免算法,每次增长1,第四个RTT是9

 

 

 

相关文章:

【网路通信基础与实践番外二】TCP协议的流量控制和拥塞控制以及二者区别和例题

TCP协议是端对端的协议&#xff0c;因此在数据进行传输的过程受发送方&#xff0c;数据通道&#xff0c;接收方三方状态的影响。我们用水龙头来比喻数据发送方&#xff0c;水管来比喻数据通道&#xff0c;水桶来表示数据接收方。 图(a)表示水桶太小&#xff0c;来不及接受注入…...

SpringBoot3+Vue3开发后台管理系统脚手架

后台管理系统脚手架 介绍 在快速迭代的软件开发世界里&#xff0c;时间就是生产力&#xff0c;效率决定成败。对于构建复杂而庞大的后台系统而言&#xff0c;一个高效、可定制的后台脚手架&#xff08;Backend Scaffold&#xff09;无疑是开发者的得力助手。 脚手架 后台脚…...

OpenFeign微服务部署

一.开启nacos 和redis 1.查看nacos和redis是否启动 docker ps2.查看是否安装nacos和redis docker ps -a3.启动nacos和redis docker start nacos docker start redis-6379 docker ps 二.使用SpringSession共享例子 这里的两个例子在我的一个博客有创建过程&#xff0c…...

【C语言】数组(下)

【C语言】数组&#xff08;下&#xff09; 6、二维数组的创建6.1二维数组的概念6.2二维数组的创建 7、二维数组的初始化7.1不完全初始化7.2完全初始化7.3按照行初始化7.4初始化时可以省略行&#xff0c;但是不能省略列 8、二维数组的使用8.1 二维数组的下标8.2二维数组的输入和…...

cGANs with Projection Discriminator

基于映射鉴别器的CGAN 模型中&#xff0c;判别器&#xff08;Discriminator&#xff09;不是通过将条件信息简单地与特征向量拼接&#xff08;concatenate&#xff09;来使用条件信息&#xff0c;而是采用一种基于投影的方式&#xff0c;这种方式更加尊重条件信息在底层概率模…...

mysql学习教程,从入门到精通,SQL HAVING 子句(32)

1、SQL HAVING 子句 当然&#xff01;HAVING 子句在 SQL 中用于对分组后的结果进行过滤。它通常与 GROUP BY 子句一起使用&#xff0c;以便对聚合函数&#xff08;如 SUM(), COUNT(), AVG(), MAX(), MIN() 等&#xff09;的结果进行条件筛选。 以下是一个示例&#xff0c;假设…...

JavaScript while循环语句

While语句包括一个循环条件和一段代码块&#xff0c;只要条件为真&#xff0c;就不断循环执行代码块。 while(条件){语句;} var i0;while(i<100){console.log(i);i1;} 注意&#xff1a;所有的for循环都可以改写为while循环...

49天精通Java(Day 2):Java的基本语法

上期内容回顾 在上一期的内容中&#xff0c;我们介绍了Java的基本概念、历史背景&#xff0c;并完成了JDK 1.8的安装与环境配置。你还编写并运行了第一个简单的Java程序“Hello, World!”。今天&#xff0c;我们将深入探讨Java的基本语法&#xff0c;包括变量、数据类型、运算…...

uni-app之旅-day01-home页

首页 3.0 创建 home 分支 &#x1f355;&#x1f355;&#x1f355;运行如下的命令&#xff0c;基于 master 分支在本地创建 home 子分支&#xff0c;用来开发和 home 首页相关的功能git branch(查看分支)git checkout -b home(创建home分支) 3.1 配置网络请求 &#x1f32…...

Vue3轻松实现导出Excel文件功能

文章目录 1.前言2.安装插件3.案例3.1 定义表格数据,设置 id 选择器3.2 据所选 dom 对象生成 sheetbook3.3 写入文件3.4 生成 xlsx文件4.完整代码1.前言 前端常用的导出 Excel的 js 库是 xlsx,但是 xlsx不能设置样式。要想设置样式,必要要结合 xlsx-style 插件一起使用,但是…...

在Kali Linux中使用VNC和iptables配置xrdp以实现远程连接

在Kali Linux中&#xff0c;使用VNC和iptables配置xrdp以实现远程连接涉及几个步骤。不过&#xff0c;值得注意的是&#xff0c;VNC和xrdp是两种不同的远程桌面协议&#xff0c;它们通常不会在同一配置中同时使用&#xff08;除非有特殊的网络架构需求&#xff09;。然而&#…...

小徐影院:Spring Boot技术下的影院革新

第四章 系统设计 4.1 系统的功能结构图 通过系统需求分析&#xff0c;本小徐影城管理系统的功能结构设计如图4-1所示&#xff1a; 图4-1 系统功能图 4.2 系统数据库设计 4.2.1 数据库E-R图 在该系统的信息中&#xff0c;由于数据库的支持&#xff0c;我们可以对数据库进行收集…...

命名空间

在 C 中&#xff0c;变量、函数和类都是大量存在的&#xff0c;这些变量、函数和类的名称将都存在于全局作用域中&#xff0c;可能会导致很多冲突&#xff0c;使用命名空间的目的是对标识符的名称进行本地化&#xff0c;以避免命名冲突或名字污染&#xff0c;namespace 关键字的…...

使用 Elastic 将 AI 摘要添加到你的网站

作者&#xff1a;来自 Elastic Gustavo Llermaly 我们目前所知道的搜索&#xff08;搜索栏、结果、过滤器、页面等&#xff09;已经取得了长足的进步&#xff0c;并实现了多种不同的功能。当我们知道找到所需内容所需的关键字或知道哪些文档包含我们想要的信息时&#xff0c;尤…...

dOOv:Java 数据验证与映射库(简化业务逻辑)

dOOv 是一个为 Java 开发人员设计的轻量化库&#xff0c;专注于数据验证和对象间的映射。与传统的验证框架不同&#xff0c;dOOv 通过提供简洁、声明式的 API&#xff0c;使得开发者可以轻松地编写、扩展和维护验证和映射规则。其设计灵感源自领域驱动设计&#xff08;DDD&…...

Arthas sc(查看JVM已加载的类信息 )

文章目录 二、命令列表2.2 class/classloader相关命令2.2.5 sc&#xff08;查看JVM已加载的类信息 &#xff09;举例1&#xff1a;模糊搜索&#xff0c;xx包下所有的类举例2&#xff1a;打印类的详细信息举例3&#xff1a;打印出类的Field信息 本人其他相关文章链接 二、命令列…...

OCR 行驶证识别 离线识别

目录 正页识别 副页识别 全部识别 OCR 行驶证识别 离线识别 正页识别 副页识别 全部识别...

PHP泛目录生成源码,可生成长尾关键词页面,带使用方法视频教程

介绍&#xff1a; 真正的好东西&#xff0c;搞网站优化seo从业必备。可以快速提升网站权重&#xff0c;带来的流量哗哗的 PHP泛目录生成源码 可生成新闻页面和关键词页面 带使用方法视频教程 泛目录可以用来提升网站收录和排名 合理运用目录可以达到快速出词和出权重的效果…...

LeetCode题练习与总结:丑数--263

一、题目描述 丑数 就是只包含质因数 2、3 和 5 的正整数。 给你一个整数 n &#xff0c;请你判断 n 是否为 丑数 。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;n 6 输出&#xff1a;true 解释&#xff1…...

初识C语言(五)

前言 本文章就代表C语言介绍以及了解正式完成&#xff0c;后续进行具体分析和详细解析学习。知识根深蒂固才可以应付后来的学习&#xff0c;地基要打好&#xff0c;后续才会轻松。 十四、结构体 结构体是C语言中最最重要的知识点&#xff0c;使得C语言有能力描述复杂的类型。 …...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

Python的__call__ 方法

在 Python 中&#xff0c;__call__ 是一个特殊的魔术方法&#xff08;magic method&#xff09;&#xff0c;它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时&#xff08;例如 obj()&#xff09;&#xff0c;Python 会自动调用该对象的 __call__ 方法…...

机器学习复习3--模型评估

误差与过拟合 我们将学习器对样本的实际预测结果与样本的真实值之间的差异称为&#xff1a;误差&#xff08;error&#xff09;。 误差定义&#xff1a; ①在训练集上的误差称为训练误差&#xff08;training error&#xff09;或经验误差&#xff08;empirical error&#x…...

VUE3 ref 和 useTemplateRef

使用ref来绑定和获取 页面 <headerNav ref"headerNavRef"></headerNav><div click"showRef" ref"buttonRef">refbutton</div>使用ref方法const后面的命名需要跟页面的ref值一样 const buttonRef ref(buttonRef) cons…...