【TCP】滑动窗口、流量控制 以及拥塞控制

news2024/11/25 7:53:00

滑动窗口、流量控制 以及拥塞控制

  • 1. 滑动窗口(效率机制)
  • 2. 流量控制(安全机制)
  • 3. 拥塞控制(安全机制)

1. 滑动窗口(效率机制)

TCP 使用 确认应答 策略,对每一个发送的数据段,都要给一个 ACK 确认应答。收到 ACK 后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。

在这里插入图片描述

既然这样一发一收的方式性能较低,那么我们一次发送多条数据,使用滑动窗口,就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)。
滑动窗口存在的意义就是在保证可靠性的前提下,尽量提高效率。

在这里插入图片描述

  • 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是 4000 个字节(四个段)。
  • 发送前四个段的时候,不需要等待任何 ACK,直接发送
  • 收到第一个 ACK 后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;
    (相当于一份等待时间等待多份 ACK, 当然不能不等,可靠传输的灵魂就是确认应答, 若没有 ACK,可靠传输就形同虚设。)
  • 操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;
  • 在一定范围内,窗口越大,传输速率就越快,网络的吞吐率就越高

在这里插入图片描述

那么如果出现了丢包,如何进行重传?这里分两种情况讨论。

  • 情况一:数据包已经抵达,ACK 被丢了。

在这里插入图片描述
这种情况下,部分 ACK 丢了并不要紧,因为可以通过后续的ACK进行确认.
ACK 的确认号有特定含义,保证后一条 ACK 覆盖前一条,
比如并没有收到 1001 ACK, 但是收到了 2001 ACK 就说明 2001 之前的数据全部已经收到了
若发送 4001 ~ 5000 之前,只收到了 4001, 但是它的意思是,4001 之前的都收到了,窗口就可以一次往下挪动 4 个。

  • 情况二:数据包就直接丢了

在这里插入图片描述

  • 当某一段报文段丢失之后,发送端会一直收到 1001 这样的 ACK,就像是在提醒发送端 “我想要的是 1001” 一样;
  • 如果发送端主机连续三次收到了同样一个 “1001” 这样的应答,就会将对应的数据 1001 - 2000 重新发送;
  • 这个时候接收端收到了 1001 之后,再次返回的 ACK 就是 7001 了(因为2001 - 7000)接收端其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中;
    重传只需要把丢的数据重传就行了,后面已经传过的数据不用再传了。

这种机制被称为 “高速重发控制”(也叫 “快重传”)。
(为什么说是 “快” 重传,因为可能收到三个连续相同的 ACK 的时间内还没有触发超时机制,也就是还没超时呢,但是不等触发超时,直接就重传了。)

2. 流量控制(安全机制)

流量控制是滑动窗口的延伸,目的是为了保证可靠性。

  • 在一定范围内,滑动窗口越大传输效率就越高,但是不能只考虑发送方,不考虑接收方,
  • 接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。

因此 TCP 支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(Flow Control);

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

在这里插入图片描述

  • 接收端如何把窗口大小告诉发送端呢?
    回忆我们的 TCP 首部中,有一个16 位窗口字段,就是存放了窗口大小信息;

  • 那么问题来了,16 位数字最大表示 65535,那么 TCP 窗口最大就是 65535 字节么?
    实际上,TCP 首部40字节选项中还包含了一个窗口扩大因子 M,实际窗口大小是 窗口字段的值左移 M 位即 65535 * 2 ^M

3. 拥塞控制(安全机制)

拥塞控制,也是滑动窗口的延伸,限制滑动窗口的发送速率。
拥塞控制描述的是发送方到接收方整个链路直接的拥堵情况。

  • 最终的滑动窗口的大小 = Min (流量控制窗口,拥塞控制窗口)

虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。
但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。

  • 发送方开始时以一个较小的窗口来发送数据,
  • 若数据很流畅到达,就逐渐加大窗口大小,
  • 若加大到一定程度出现丢包,就减小窗口,
  • 通过反复的增大/减小过程,逐渐找到一个合适的范围,拥塞窗口就在这个范围中不断变化,达到一个 “动态平衡”。

具体拥塞窗口是怎么变化的呢 ?

在这里插入图片描述

  1. 慢开始
    初始值 窗口大小为 1, 然后以指数级别增长,“慢开始” 只是指初使时慢,但是增长速度非常快。
  2. 拥塞避免
    窗口值到达 ssthresh 时,从指数增长变为 线性增长。
  3. 网络拥塞
    出现大量丢包情况,说明网络拥塞了,拥塞窗口大小直接变为 1 。ssthresh 阈值变为此时拥塞窗口大小的一半,图中就是从 变为 24 的一半 12 。
    (少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为网络拥塞;)
  4. 然后重新慢开始,循环这个过程。

当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降;

  • 为什么使用指数级别的增长速度 ?
    因为希望能快速接近 ssthresh 阈值, 既希望速度快,又希望不大量丢包,如果初始情况给的窗口大小很小,可能合适的值是个很大的值,那么使用指数增长的话,能够很快的接近这个值。

  • ssthresh 的意义 ?
    决定了什么时候从指数增长变为线性增长

  • 拥塞窗口最理想的大小 ?
    ssthresh 值与 出现拥塞的这个值之间是最理想的效果,这个范围之间传输速率较快,并且没有大量丢包。

  • 为什么出现拥塞时,直接让窗口变为初始值 1 ?
    因为网络的情况很复杂,不稳定,如果出现大量丢包,很可能速度降下来一点是不能解决问题的,速度降得太慢还会有可能出现持续丢包,就会对网络质量带来很大影响,一下让窗口变得很小,就是期望这次传输一定能成功。

拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。

常见面试题:

  1. UDP 本身是无连接,不可靠,面向数据报的协议,如果要基于传输层UDP协议,来实现一个可靠传输,应该如何设计?
  2. UDP 大小是受限的,如果要基于传输层UDP协议,传输超过64K的数据,应该如何设计?

以上两个问题答案类似,都可以参考TCP的可靠性机制然后在应用层实现类似的逻辑:
如:

  • 引入序列号,保证数据顺序;
  • 引入确认应答,确保对端收到了数据,保证可靠传输;
  • 引入超时重传,如果隔一段时间没有应答,就重发数据;
  • 引入滑动窗口;
  • 引入窗口扩大选项;
  • 引入流量控制
  • 引入拥塞控制
  • ……

好啦! 以上就是对 TCP 滑动窗口、流量控制 以及拥塞控制的讲解,希望能帮到你 !
评论区欢迎指正 !

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

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

相关文章

机器学习第七课--情感分析系统

分词 分词是最基本的第一步。无论对于英文文本,还是中文文本都离不开分词。英文的分词相对比较简单,因为一般的英文写法里通过空格来隔开不同单词的。但对于中文,我们不得不采用一些算法去做分词。 常用的分词工具 # encodingutf-8 import …

Linux C 多线程

为什么会有线程? ————————>>>> 进程实现多任务的缺点: 进程间切换的计算机资源开销很大,切换效率非常低进程间数据共享的开销也很大 线程和进程的关系 线程是进程的一个执行单元,是进程内的调度实体。比进程…

应用:使用#todo标签,清理未完成笔记 | Obsidian实践

各位【见睿思齐】的朋友,好久不见。断更了这么久,非常抱歉。起初是因为家里出了些事情,不得不断更了一段时间;后来是因为断更太久,找不回写作的感觉,于是又断更了更久的时间……总之是太不应该。最近读了一…

ESLint+Prettier+VSCode编程规范

编程规范 ESLintPrettierESLint和Prettier配合解决代码格式化问题1. 在VSCode搜索Prettier插件安装2. 创建prettier配置文件3. 在VSCode中设置3.1 找到左下角设置图标,点击设置3.2 但是对VSCode 而言,默认一个 tab 等于 4 个空格,而 ESLint 希…

【Hierarchical Coverage Path Planning in Complex 3D Environments】

Hierarchical Coverage Path Planning in Complex 3D Environments 复杂三维环境下的分层覆盖路径规划 视点采样全局TSP 算法分两层,一层高级一层低级: 高层算法将环境分离多个子空间,如果给定体积中有大量的结构,则空间会进一步细…

基于PyTorch搭建FasterRCNN实现目标检测

基于PyTorch搭建FasterRCNN实现目标检测 1. 图像分类 vs. 目标检测 图像分类是一个我们为输入图像分配类标签的问题。例如,给定猫的输入图像,图像分类算法的输出是标签“猫”。 在目标检测中,我们不仅对输入图像中存在的对象感兴趣。我们还…

软件工程之总体设计

总体设计是软件工程中的一个重要阶段,它关注整个系统的结构和组织,旨在将系统需求转化为可执行的软件解决方案。总体设计决定了系统的架构、模块划分、功能组织以及数据流和控制流等关键方面。 可行性研究 具体方面:经济可行性、技术可行性…

如何正确安装滚珠螺杆螺母?

在安装滚珠螺母时,相信很多人都遇到过装反这个问题,滚珠螺杆螺母是通过高精度的加工和配合实现传递转矩和运动的,如果将滚珠螺杆螺母反过来装,会导致导向槽和调整垫片位置不正确,使得整个螺杆系统的传动精度降低&#…

sketch for Mac快捷键大全

你可以在sketch中使用键盘快捷键来加快你的设计过程。要使用键盘快捷键,请同时按下下列列表的所有键。有些命令只能根据你在做什么或者你选择了什么才启用,所有把命令分成了下列不同的部分。 sketch下载地址:sketch 破解-Sketch for mac(专业…

Linux 信号集 及其 部分函数

这几个函数都是对自己自定义的信号集操作 int sigemptyset(sigset_t *set) 功能:清空信号集中的数据,将所有的标志位置为0 参数:set需要操作的信号集 返回值:成功0失败-1 int sigfillset(sigset_t *set) 功能:清空…

各个浏览器离线安装包获取方式

前言 我们一般去浏览器官网下载所谓的官方版浏览器,但是如今呢,下载的都是在线安装包,大小大约1~2MB,安装时电脑必须联网,每次都要从网络上下载。就像下面这样的: 在线安装包的运行必须有网络环境&#…

批量使用cdo 修改分辨率的方法

文件夹里有很多这种grib文件 怎么有2.3T啊,好大,一个一个改太浪费时间了 现在我想用cdo 批量他们的分辨率都降低一些,怎么做呢? find . -name *low.grib |xargs -I{} cdo remapbil,r144x72 {} {}_low.nc 思路:使用 find 命令找到…

小型网络实验组网

路漫漫其修远兮,吾将上下而求索 时隔多日,没有更新,今日一写,倍感教育的乐趣。如果让我每天发无意义的文章,我宁可不发。 实验拓扑 实验要求 (1)内网主机采用DHCP分配IP地址 (2&…

6-3 pytorch使用GPU训练模型

深度学习的训练过程常常非常耗时,一个模型训练几个小时是家常便饭,训练几天也是常有的事情,有时候甚至要训练几十天。 训练过程的耗时主要来自于两个部分,一部分来自数据准备,另一部分来自参数迭代。 当数据准备过程还…

分享一下微信公众号怎么添加砸金蛋链接

一、砸金蛋活动的优势 砸金蛋活动是一种非常有趣且吸引人的互动方式,在微信公众号中添加砸金蛋链接有以下优势: 提高用户参与度:砸金蛋活动能够激发用户的参与度和好奇心,让用户感到有乐趣和刺激。通过砸金蛋的方式,…

现在全国融资融券两融利率最低是多少?哪家证券公司券商费率低?

融资融券是指投资者通过向券商借入资金(融资)或借入证券(融券),以达到获得更高收益、降低交易风险、提高资金利用效率的目的。通过融资,投资者可以用借入的资金买入更多的证券;通过融券&#xf…

乐器商城小程序开发全攻略

随着互联网的普及和电子商务的快速发展,越来越多的人开始通过在线购物来满足自己的需求。而乐器作为一种特殊的商品,其在线销售市场也在不断扩大。为了满足这一需求,许多乐器商家开始开发自己的小程序商城,以提供更加便捷、高效的…

python使用SMTP发送邮件

SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。 Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。 首先,我们来构造一个最简单的…

[BJDCTF2020]Mark loves cat foreach导致变量覆盖

这里我们着重了解一下变量覆盖 首先我们要知道函数是什么 foreach foreach (iterable_expression as $value)statement foreach (iterable_expression as $key > $value)statement第一种格式遍历给定的 iterable_expression 迭代器。每次循环中,当前单元的值被…

184_Python 在 Excel 和 Power BI 绘制堆积瀑布图

184_Python 在 Excel 和 Power BI 绘制堆积瀑布图 一、背景 在 2023 年 8 月 22 日 微软 Excel 官方宣布:在 Excel 原生内置的支持了 Python。博客原文 笔者第一时间就更新到了 Excel 的预览版,通过了漫长等待分发,现在可以体验了&#xf…