47、TCP的流量控制

从这一节开始,我们学习通信双方应用进程建立TCP连接之后,数据传输过程中,TCP有哪些机制保证传输可靠性的。本节先学习第一种机制:流量控制。


窗口与流量控制

首先,我们要知道的是:什么是流量控制?使用流量控制是为了解决什么问题?

在这之前,我们学习过“接收窗口”的概念,其实也就是接收缓存的大小,能够容纳多少字节的数据,这个数值是有限的。所以接收窗口在容纳了足够的数据量之后,就没有缓存再接收对方发来的数据了。如果这时对方还在不断地发来数据,那么这些数据到达接收方之后,接收方由于没有空余的空间来容纳,来不及接收,就只能把它们丢弃掉。

所以,必须要有一种机制能够解决这种问题,这就是流量控制。流量控制就是为了能够控制发送方的发送速率,使其不要太快,要能够让接收方来得及处理

可以用比较经典的原理图来说明流量控制,如下图:

在这个图中,为了方便叙述原理,假设发送方只简单的发送数据,接收方只简单的接收数据,并设置接收方的接收窗口大小为400个字节。

一开始,发送方发送了两个大小为100字节数据的报文段,接收方收到后进行确认回复:ack=201,rwnd=200。意思是,截止到序号为200的报文,我已经都收到了,我期望你下一个发来的报文的序号是201,现在我的接收窗口大小是200字节,你最多再给我发200字节的数据。

发送方知道这个情况之后,接着发送了200个字节的数据。这时候接收方给出接收窗口大小为0的确认报文,告诉发送方:我目前已经没有接收缓存了,暂时先不要发送数据了。

接收方通过在确认报文中给出自己当前接收窗口的大小,使发送方知道应该向对方发送多少数据量,就是TCP流量控制的方法。


“零窗口”死锁现象

了解了上面流量控制的过程之后,可能会想一个问题:接收方最后发送窗口值大小为零的确认报文之后,发送方就会暂停发送数据,等待接收方告诉缓存有空间了再继续发送。可是如果接收方将“缓存有空间”的消息告诉发送方的时候,这个消息不巧在传输过程中丢失了,那么发送方会不会一直等下去呢?

这个现象就叫做“零窗口”死锁现象,由于发送方没收到“接收方缓存有空间”的消息,所以发送方一直以为接收方当前接收缓存没有空间。所以双方就会产生这样一种“死锁”的局面

为了解决这种死锁问题,所以每一个TCP连接都会设置有一个“坚持定时器”。这个定时器的作用是:从收到对方发来“窗口大小为零”的报文开始,启动定时器,等到定时器到期如果还没有收到对方发来“接收缓存有空间”的消息,那么就主动向对方发送一个“零窗口探测”报文,这个探测报文只带有一个字节的数据,目的就是为了探测一下对方窗口大小有没有改变。

对方收到这个探测报文后,给出确认报文,其中包含了当前窗口值,如果当前窗口值已经不是零了,这个死锁的局面就打破了,发送方可以继续发送数据;但如果当前窗口值仍然为零,那么发送方将再次启动“坚持定时器”,时间到就再次发送探测报文。

学到这里,又出现一个问题:既然接收方的窗口值都为零了,也就意味着接收方不能再接收数据了,那么为什么发送方的“零窗口探测”报文能被接受呢?

这其实是TCP的一个规定:当接收窗口大小为零时,也必须接收“零窗口探测”报文。还有一个前面学过的,首部中URG位被设置为1的紧急报文,也是即使窗口值为零时必须被接收。


糊涂窗口综合症

糊涂窗口综合症主要反映的是:接收方应用进程和接收缓存交互数据的时候效率低下,从而导致TCP传输效率低下的问题。

比如这样一个情景:接收方的窗口值为零,意味着当前接收缓存已满,但是上层的应用进程一次只读取一个字节的数据,这样缓存中就有了一个字节的空间,这时接收方给发送方发出确认,表明自己的接收窗口值是1,你可以发来1个字节的数据。

这样的话,可以想一下,发送方要把这一个字节的数据加上至少20字节的TCP首部,再加上至少20字节的IP首部,层层封装,就会造成传输首部信息的开销大,而实际的有用数据才只有一个字节。如此反复,一次只有一个字节的有效数据在传输,就导致TCP传输效率的低下,这就是糊涂窗口综合症的现象。

要解决这种问题,可以在接收方和发送方分别设置一些机制,双方配合起来,使得接收方不要有了一点空间就立即发送确认报文,同时发送方也不要每次只发送一个很小的报文段。

可以在接收方设置:等到缓存中有了能够容纳一个最大长度报文段的空间时,或者缓存空间有一半是空余的,就可以给发送方发去确认,通告自己的接收窗口大小。

也可以在发送方使用Nagle算法:当数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。

两种方法配合起来使用,可以有效避免糊涂窗口综合症的现象发生。


本节内容我们学习了TCP规定在数据传输过程中的流量控制的方法原理,另外还介绍了“零窗口”死锁和糊涂窗口综合症两个可能会发生的问题和相应的解决办法。下一节,我们学习TCP的可靠传输。

参考教材:杨英鹏《计算机网络原理与实践》

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

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

相关文章

【GPT引领前沿】GPT4技术与AI绘图

推荐阅读: 1、遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型应用 2、GPT模型支持下的Python-GEE遥感云大数据分析、管理与可视化技术 GPT对于每个科研人员已经成为不可或缺的辅助工具,不同的研究领域和项目具有不同的需求。例如在科研编程…

Mybatis的关联关系配置一对一,一对多,多对多的映射关系

目录 关联关系映射 一对一关联: 一对多关联: 多对多关联: 导入数据库表 一对多 一对一 多对多 关联关系映射 关联关系映射在Mybatis中主要通过三种方式实现:一对一关联和一对多关联及多对多关联。 一对一关联:…

RHCA之路---EX280(5)

RHCA之路—EX280(5) 1. 题目 Using the example files from the wordpress directory under http://materials.example.com/exam280/wordpress create a WordPress application in the farm project For permanent storage use the NFS shares /exports/wordpress and /export…

【STM32】学习笔记-PWR(Power Control)电源控制

PWR(Power Control)电源控制 PWR(Power Control)电源控制是一种技术或设备,用于控制电源的开关和输出。它通常用于电源管理和节能,可以通过控制电源的工作状态来延长电子设备的使用寿命,减少能…

QT建立TCP服务器

QT core gui network *************************************************** #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器头文件 #include <QTcpSocket>//客户端头文件 #include <QList>//存放客户端…

网易低代码引擎Tango正式开源

一、Tango简介 Tango 是一个用于快速构建低代码平台的低代码设计器框架,借助 Tango 只需要数行代码就可以完成一个基本的低代码平台前端系统的搭建。Tango 低代码设计器直接读取前端项目的源代码,并以源代码为中心,执行和渲染前端视图,并为用户提供低代码可视化搭建能力,…

N5235B是德科技网络分析仪50GHz

181/2461/8938对无源元器件和简单的有源器件执行基本分析 适用于对成本非常敏感的应用&#xff0c;可以在高达 50 GHz 的频率范围内精确测量 S 参数 具有出色的性价比&#xff0c;可用于微波器件制造测试 可以配置经济型解决方案&#xff0c;用于信号完整性测量和材料表征 …

Android列表片段

下面创建第二个片段WorkoutFragment&#xff0c;它包含不同训练项目构成的一个列表&#xff0c;用户可以从这个列表中选择训练项目。 列表视图是只包含一个列表的片段 列表片段是一种专门处理列表的片段&#xff0c;它会自动绑定到一个列表视图&#xff0c;所以不需要另外创建…

关于人工智能的担忧

人工智能的快速发展引发了一系列关于其潜在风险和担忧的讨论。以下是一些常见的人们对人工智能的担忧&#xff1a; 失业问题&#xff1a;人工智能的出现可能会导致很多工作岗位的消失&#xff0c;特别是那些需要重复性劳动的工作。人们担心机器取代人类工作将导致大规模失业和社…

String.format() 格式化字符串的方法, 不同占位符表示的含义及使用方式

学习目标&#xff1a; 目标如下&#xff1a; String.format() 格式化字符串的方法&#xff0c; 不同占位符表示的含义及使用方式 学习内容&#xff1a; 内容&#xff1a; 占位符类型 String.format()方法是一种格式化字符串的方法 字符串&#xff1a;一个占位符"%s&q…

Java设计模式:四、行为型模式-08:策略模式

文章目录 一、定义&#xff1a;策略模式二、模拟场景&#xff1a;策略模式三、违背方案&#xff1a;策略模式3.0 引入依赖3.1 工程结构3.2 优惠券折扣计算类3.3 单元测试 四、改善代码&#xff1a;策略模式4.1 工程结构4.2 策略模式结构图4.3 优惠券折扣实现4.3.1 定义优惠券接…

js中如何判断一个变量的数据类型?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐typeof 运算符⭐instanceof 运算符⭐Object.prototype.toString 方法⭐Array.isArray 方法⭐自定义类型检查⭐null 和 undefined 检查⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订…

Python综合案例(基本地图使用)

一、基本地图的使用 基本代码&#xff1a; """ 演示地图可视化的基本使用 """ from pyecharts.charts import Map from pyecharts.options import VisualMapOpts# 准备地图对象 map Map() # 准备数据 data [("北京", 99),("…

鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显…

static关键字

static 是Java中的一个关键字&#xff0c;它可以用于修饰类的成员变量和方法&#xff0c;具有特殊的含义和用途。下面是关于static关键字的主要用法和含义&#xff1a; 静态变量&#xff08;Static Variables&#xff09;&#xff1a; 静态变量也称为类变量&#xff0c;它们属于…

Qt鼠标点击事件处理:显示鼠标点击位置(完整示例)

Qt 入门实战教程&#xff08;目录&#xff09; 前驱文章&#xff1a; Qt Creator 创建 Qt 默认窗口程序&#xff08;推荐&#xff09; 什么是事件 事件是对各种应用程序需要知道的由应用程序内部或者外部产生的事情或者动作的通称。 事件&#xff08;event&#xff09;驱动…

【Java 基础篇】Java多态:让你的代码更灵活而强大

多态是面向对象编程中的一个重要概念&#xff0c;它允许我们在不同的对象上调用相同的方法&#xff0c;但根据对象的不同&#xff0c;可以产生不同的行为。在 Java 中&#xff0c;多态性是一个强大的特性&#xff0c;它有助于代码的可扩展性和可维护性。本篇博客将深入探讨 Jav…

FinClip 支持创建 H5应用类小程序;PC 终端 优化升级

FinClip 的使命是使您能够通过小程序解决关键业务流程挑战&#xff0c;并完成数字化转型。不妨让我们看看本月产品与市场发布亮点&#xff0c;是否有助于您实现目标。 产品方面的相关动向&#x1f447;&#x1f447;&#x1f447; FinClip 支持创建 H5应用类小程序 近期我们…

Redis图文指南

1、什么是 Redis&#xff1f; Redis&#xff08;REmote DIctionary Service&#xff09;是一个开源的键值对数据库服务器。 Redis 更准确的描述是一个数据结构服务器。Redis 的这种特殊性质让它在开发人员中很受欢迎。 Redis不是通过迭代或者排序方式处理数据&#xff0c;而是…

Verilog零基础入门(边看边练与测试仿真)-笔记

文章目录 第一讲第二讲第三讲第四讲 第一讲 1、testbench 没有端口&#xff0c;所以没括号 2、testbench 输入端 之后要变动 所以定义为reg 3、#10 &#xff1a;过10个时间单位 &#xff1b;’timescale 1ns/10ps 即 1ns 的时间单位 10ps的时间精度 4、reg 型变量赋值的时候 用…