TCP发送窗口、接收窗口以及其工作原理

news2024/11/24 17:22:35
2475c91e4e90ee6462a48c4d7b736c57.png
1*KvfIrP_Iwq40uVdRZYGnQg.png

上面的图表是从发送方的角度拍摄的快照。我们可以将数据分为4组:

1.已发送并已确认的字节(蓝色)2.已发送但尚未确认的字节(黄色)3.未发送但接收方准备好接收的字节(绿色)4.未发送且接收方未准备好接收的字节(灰色)

第3类也称为可用窗口,因为这是发送方可以使用的窗口。

发送窗口包括黄色和绿色部分。这些字节要么已经被发送,要么可以被发送。

9b372e3520f51ee1ade3aabd50ba1d9f.png
1*OqqxQKu4ZGasXzIlUZ9lyw.png

可用窗口在发送方发送了21-25字节并使用了可用窗口中的所有字节时可能为空。发送窗口保持不变。

933a4f9db5b7983476ed173b6e29bff8.png
1*JdTCgvYpVPRDcLyVb8Rwsg.png

当发送方接收到16-19字节的确认时,发送窗口向右滑动4个字节。队列中的接下来的字节会有一个更新的可用窗口。

f1026c5dc78e6c39c25d881388cb8f02.png
1*9zFu_scvenahSK6m-khSjw.png

一些定义可以帮助我们更好地理解本文后面的复杂情况:

SND.WND,表示发送窗口•SND.UNA,表示发送未确认指针,指向发送窗口的第一个字节•SND.NXT,表示发送下一个指针,指向可用窗口的第一个字节

9a1b729b410101105300ae2335ade3f7.png
1*IYBc3_OiPWAZ7JCvIaktkA.png

基于这些定义,我们可以用以下公式表示可用窗口的大小。

接收窗口

fc9c8544e9050abacec25d79341dd6f5.png
1*SbgJAvyVKyXYvPLuoBbGtA.png

接收窗口分为3个类别:

1.已接收并已确认的字节2.尚未接收但发送方允许发送的字节3.尚未接收且发送方可能不允许发送的字节

第2类被称为接收窗口,也可以称为RCV.WND

与发送窗口类似,有一个指针RCV.NXT,表示接收窗口的第一个字节。

946ad2b58f2ce87f2ecb8f3a67a713b4.png
1*u3KoxvVK-rrM1g4gX6fbZQ.png

接收窗口并非静态。如果服务器运行得高效,接收窗口可以扩展。否则,它可能会缩小。

接收方通过在TCP段头中的窗口字段中指示大小来传达其接收窗口。当发送方收到它时,这个窗口大小就成为了可用窗口。

发送和接收段需要时间。因此,接收窗口在特定时刻不等于可用窗口。

简化的示例

让我们模拟一次请求和响应,以更好地理解滑动窗口的工作原理。

有两个修改简化了我们的计算。

1.我们忽略了最大段大小(MSS)。MSS根据所选的网络路由而变化。2.我们使接收窗口等于可用窗口,而且在整个过程中都保持不变。

d7cd61bc376017227d74031a04d3dd79.png
1*sAF4A2TyNeItzw2yK0xI9g.png

上面是一个显示了10个步骤示例的图表。

客户端请求一个资源,服务器以三个段响应它:

1.50字节的头部2.80字节的正文部分13.100字节的正文部分2

每一方都可以同时是发送方和接收方。

我们假设客户端的发送窗口(SND.WND)为300字节,接收窗口(RCV.WND)为150字节。因此,服务器的SND.WND为150字节,RCV.WND为300字节。

22b2cb96ae3a78f8510fbff9dc6cf714.png
1*cU9TEaEoezDwvw__3G1DFw.png

这是客户端的起始状态。

我们假设它之前已经从服务器接收了300字节,因此RCV.NXT指向301。

由于它还没有发送任何内容,SND.UNA和SND.NXT都指向1。

e44329017e7a4af05629c53192b3e620.png
1*IYBc3_OiPWAZ7JCvIaktkA.png

根据这个公式,客户端的可用窗口大小是1 + 300 - 1 = 300

707e4923eb17410e10d540e347c8d112.png
1*kfa6ZdhSR_VJggJ2abUSAQ.png

这是服务器的起始状态,反映了另一侧的状态。

因为它已经发送了300字节,SND.UNA和SND.NXT都指向301。

由于客户端还没有发送任何请求,RCV.NXT指向1。

服务器的可用窗口是301 + 150 - 301 = 150

现在,第1步开始了。

客户端发送了第一个100字节的请求。在这一刻,窗口发生了变化。

•这100字节已发送但尚未确认。因此,SND.NXT向右滑动了100字节。•其他指针保持不变。

可用窗口变为1 + 300 - 101 = 200

c0c308513074b249643857b37002b45a.png
1*ug0laVIMWQ3HGG-kPjZ0KA.png

在第2步,我们关注了服务器。

•当服务器接收到请求时,RCV.NXT向右滑动了100字节。•然后发送了带有ACK的50字节响应。这50字节已发送但尚未确认,所以SND.NXT向右移动了50个字节。•SND.UNA保持不变。

可用窗口变为301 + 150 - 351 = 100

f117a7e373e96dbc1af1e1c214d6fb84.png
1*GAZqLwbVGj2yqUnm5DyI4w.png

移动到客户端。

•当客户端接收到50字节的响应时,RCV.NXT向右滑动了50字节。•当它收到前面发送的100字节的ACK时,SND.UNA向右滑动。•由于客户端没有发送任何数据,SND.NXT保持不变。

可用窗口变为101 + 300 - 101 = 300

7a59c0746c3ca5c7098bb0f5c4ad3b78.png
1*50UitYxS9XW3N4XV2Z7tOg.png

再次移动到服务器的一端。

可用窗口是100字节。服务器可以发送80字节的段。

•SND.NXT向右滑动了80个字节。•由于前面的50字节尚未确认,SND.UNA保持不变。•由于服务器未接收任何数据,RCV.NXT保持不变。

可用窗口变为301 + 150 - 431 = 20

6fbb6b1e304e47a99a16ca066cdcc67f.png
1*soNJeyvqRj0zqDDrtBL9Fg.png

客户端接收了文件的第一部分并立即发送了ACK。

•当客户端接收到80字节的数据时,RCV.NXT向右滑动。•其他指针保持不变。

可用窗口保持在300。

a0e24c145be5cf12f4c97b04fa1beafd.png
1*QJKwuY3HvslR9601ZRWCxA.png

此时,服务器在发送第2步时接收到ACK时。

•当服务器发送50字节的响应时,SND.UNA向右滑动了50个字节。•其他指针保持不变。

d2a9230bc0f94516d992008d361b3f54.png
1*thuJ7lCYqreqxsL8nMz_ag.png

在第4步中,服务器发送了文件的第一个80字节部分,并再次收到了ACK确认。

•SND.UNA(已确认序列号)向右移动了80个字节。•其他指针保持不变。

可用窗口的计算变为431 + 150 - 431 = 150

c2256ff5c0eaac6116b8d3ba26c1d975.png
1*8sS5S0OkW0I2Vbp40nkkZQ.png

在第8步,服务器发送了文件的第二部分,共100字节。

•SND.NXT(下一个要发送的序列号)向右移动了100个字节。•其他指针保持不变。

可用窗口的计算变为431 + 150 - 531 = 50

67c72cc99278bdc60d21187edc40e181.png
1*qXP9BCX80vPpkplc5utP6Q.png

接下来,轮到客户端。

•RCV.NXT(下一个要接收的序列号)在客户端接收100字节后向右移动了100个字节。•其他指针保持不变。

可用窗口保持不变。

b76ad887cc70da67a3422731f374aeb7.png
1*LkQ7tG-_1XQROjOZ3vTC9g.png

最后,服务器接收了前一个响应的ACK。

•SND.UNA向右移动了100个字节。•其他指针保持不变。

可用窗口的计算变为531 + 150 - 531 = 150

当窗口发生变化

在之前,我们假设发送窗口和接收窗口保持不变。但在实际情况中,这个假设是不正确的,因为两个窗口中的字节存在于操作系统缓冲区中,而缓冲区中的可用空间可以调整。当我们的应用程序无法快速读取缓冲区中的字节时,可用空间会减小。

让我们看看窗口发生变化的情况,以及它如何影响可用窗口。

84373ea3f5bef4037022c7e056428c67.png
1*qyjkUdkAdsfrkRkqVlPClw.png

为了简化,本例重点关注客户端的可用窗口。在这个示例中,客户端始终是发送方,服务器是接收方。

2faafc9e638211e741db92475cbc7a75.png
1*u3KoxvVK-rrM1g4gX6fbZQ.png

当服务器发送ACK时,它还包括了更新后的窗口大小。

d1160eef6e62855f3d1c8daeeb48f79c.png
1*pkiC_TWGpIZF3aSPOz6lcA.png

一开始,客户端发送了一个150字节的请求。

•这150字节已发送但尚未得到确认。•可用窗口缩小为150字节。•发送窗口保持在300字节。

4839761489bfce8083bd7b3b5c000d4a.png
1*zs4VuHChJJ-7vWFmXyr8Ug.png

当服务器接收请求时,应用程序读取了前50字节,剩下的100字节仍然在缓冲区中,从接收窗口中占用了100字节的可用空间。因此,接收窗口缩小到了200字节。

接下来,服务器发送了一个带有更新后的200字节接收窗口的ACK。

2cf9fd1982247495f0d9fecaed83d0d0.png
1*SZDl6q22CB6kzY3P-CCHFA.png

客户端接收ACK并将其发送窗口大小更新为200。

此时,可用窗口与发送窗口相同,因为所有150字节都已得到确认。

7012d536d16dd88b22f4b0c5047ba357.png
1*6gKYyaDUdOQSEGfHh6SWdA.png

再次,客户端发送了另一个200字节的请求,使用了可用窗口中的所有可用空间。

9b77865c72bd299605e1369f6bb8266c.png
1*uJiRzHmdV4kT8lPW62bz0g.png

在服务器接收了这200字节之后,应用程序仍然运行缓慢,总共只读取了70字节,将280字节留在缓冲区中。这导致接收窗口再次缩小,现在只剩下20字节。

在ACK消息中,服务器与客户端分享了更新后的窗口大小。

d96b4345b1fac74cfb8c72803052ab76.png
1*xnUjR-R45hPoGO7qhvCHKg.png

再次,客户端在收到ACK后将其发送窗口更新为20字节,可用窗口也变为20字节。

在这种情况下,如果没有更多来自服务器的消息,客户端将停止发送大于20字节的请求,直到在后续消息中收到另一个窗口更新。

那么,如果没有更多消息来自服务器,我们会被困在20字节的可用窗口吗?

不会。为了避免这种情况,客户端的TCP定期检测窗口大小。

一旦释放更多的空间,

可用窗口就会扩大,可以发送更多的数据。

主要内容

•可用窗口的计算是理解TCP滑动窗口的关键。•要了解可用窗口的计算,我们需要理解3个指针——SND.UNA、SND.NXT和RCV.NXT。•假设窗口大小永远不会改变可以帮助我们理解整个过程。


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

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

相关文章

【C++】C++静态成员函数,类名直接调用

静态成员函数可以通过类名直接调用,不用创建对象。例如:ClassName::Func();通过类名直接调用因为不用创建对象所以不会运行类的构造方法。适合用于初始化。 参考: C【6】对静态成员函数的用法说明C调用成员函数的几种方法总结C static静态…

大数据毕业设计选题推荐-农作物观测站综合监控平台-Hadoop-Spark-Hive

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Linux 多线程编程详解

目录 为什么要使用多线程 线程概念 线程的标识 pthread_t 线程的创建 向线程传入参数 线程的退出与回收 线程主动退出 线程被动退出 线程资源回收(阻塞方式) 线程资源回收(非阻塞方式) 为什么要使用多线程 在编写代码时,是否会遇到以下的场景会感觉到难以…

LINUX入门篇【4】开发篇--开发工具vim的使用

前言: 从这一篇开始,我们将正式进入使用LINUX进行写程序和开发的阶段,可以说,由此开始,我们才开始真正去使用LINUX。 介绍工具: 1.LINUX软件包管理器yum: 1.yum的介绍: 在LINUX…

Swift--量值与基本数据类型

系列文章目录 第一章: Swift–量值与基本数据类型 文章目录 系列文章目录前言对学习过程做一个记录 变量和常量命名规范注释 元祖类型可选类型拆包 typealias 前言 对学习过程做一个记录 提示:以下是本篇文章正文内容,下面案例可供参考 变量和常量 …

十分钟理解回归测试(Regression Testing)

回归测试是一个系统的质量控制过程,用于验证最近对软件的更改或更新是否无意中引入了新错误或对以前的功能方面产生了负面影响(比如你在家中安装了新的空调系统,发现虽然新的空调系统可以按预期工作,但是本来亮的等却不亮了&#…

Leetcode刷题【hot100】盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容器。 示例…

单例模式 rust和java的实现

文章目录 单例模式介绍应用实例:优点使用场景 架构图JAVA 实现单例模式的几种实现方式 rust实现 rust代码仓库 单例模式 单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建…

uboot 和 内存地址

前言 在使用 uboot 升级的时候,有个疑问: 通过 tftp 下载的 bin 文件,我该暂存在哪段内存空间?换句话说,哪段内存空间可供我存放临时数据? 带着这个疑问,开启今天的 uboot 和 内存地址 研究之旅…

CSS特效004:hover图片,显示文字或附加层

css实战中,时常会碰见鼠标放在某个区块上,显示出一段文字或者其他附加信息。思路是利用position的层叠关系,将文字层放在图片的上面,display:none; hover的时候层 display:block。 效果图 源代码 /* * Author: 大剑师…

NR UE capability FeatureSetCombination的查看方法

下面是UEcapability中根据协议中的描述总结的NR CA和EN-DC组合的查看方法,主要内容在38.331/36.331中。比较关键的IE就是FeatureSetCombination。 FeatureSetCombination对应的是FeatureSet entries的二维矩阵。 每个FeatureSetsPerBand 包含适用于相关band combin…

伦敦金股票代码是什么?

伦敦金是跟踪实时的现货黄金价格走势的差价合约交易,它的代码一般是LLG、GOLD,但也有一些货币交易平台会显示为XAU。伦敦金不是股票交易,因此没有四位数或六位数的股票代码,但伦敦金交易品种单一,投资者不用在数千支股…

亚马逊云科技海外服务器初体验

目录 前言亚马逊云科技海外服务器概述注册使用流程实例创建性能表现用户体验服务支持初体验总结 前言 随着云原生技术的飞速发展,越来越多的企业和开发者选择云服务器来作为自己的使用工具,云原生技术的发展也促进了云服务厂商的产品发展,所…

CSS3 2D、3D转换

一、CSS3 2D转换&#xff1a; CSS3转换可以对元素进行移动、缩放、转动、拉长或拉伸。 2D变换的方法&#xff1a;translate()、rolate()、scale()、skew()、matrix()。 <style> div { width:200px; height:100px; background-color:red; /* Rotate div */ tran…

创新功能点展望:探索未来一对一交友App开发的趋势和可能性

随着社交媒体和科技不断进步&#xff0c;一对一交友App开发正处于迅猛发展的阶段。未来&#xff0c;这一领域将出现许多激动人心的创新&#xff0c;为用户带来更加个性化、安全、以及富有情感连接的体验。以下将探讨一些可能性和趋势&#xff0c;以及从中受益的用户和开发者。 …

自动计算零售数据分析指标?BI软件表示可行

随着BI技术的飞速发展&#xff0c;借助系统来计算分析指标也不是什么难事&#xff0c;即便是面对组合多变的零售数据分析指标&#xff0c;奥威BI软件也依旧可以又快又精准地完成指标计算。 BI软件可以自动计算零售数据分析指标&#xff0c;如销售额、库存量、订单量等。在计算…

MyBatis中文网

MyBatis中文网https://mybatis.net.cn/ MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Ja…

软件测试|MySQL WHERE条件查询详解:筛选出需要的数据

简介 在数据库中&#xff0c;我们常常需要从表中筛选出符合特定条件的数据&#xff0c;以便满足业务需求或获取有用的信息。MySQL提供了WHERE条件查询&#xff0c;使我们能够轻松地筛选数据。本文将详细介绍MySQL WHERE条件查询的用法和示例&#xff0c;帮助大家更好地理解和应…

[工业自动化-7]:西门子S7-15xxx编程 - PLC主站 - 电源模块

目录 前言&#xff1a; 一、主站电源PM VS PS 1.1 主站PM电源模块(PM) 1.2 主站PS电源模块 1.3 PM/PS电源模块区别 1.4 如何选择PM/PS电源 1.5 什么时候必须使用PM模块 1.6 什么时候必须使用PS模块 二、背板总线 三、电源模块的安装 前言&#xff1a; 一、主站电源PM…

制作一个用户登录界面

Flask-WTF扩展使用Python类来表示web表单。表单类只是将表单的字段定义为类变量。 再次考虑到分离的问题&#xff0c;我将使用一个新的app/forms.py模块来存储我的web表单类。首先&#xff0c;让我们定义一个用户登录表单&#xff0c;它要求用户输入用户名和密码。表单还将包括…