网络编程(12): TCP重传、滑动窗口、流量控制、拥塞控制
1、TCP重传机制
通过序列号和确认号确保可靠传输,当发送端发送数据给接收到,接收端会返回一个确认号,表示收到消息了
- 超时重传:没有在指定时间内收到
ACK报文- 超时重传的两种可能:数据包丢失、确认包丢失
- 超时重传时间
RTO:RTO较大:重发就变慢了,丢包之后需要半天才能重发,效率低RTO较小:可能没有丢包,还在等待ACK过程中,就重发了,会导致网络拥塞,进而导致更多的超时重发- 所以
RTO需要略大于报文往返的时间RTT(数据发送到接收到ACK的时间差)
- 由于网络波动问题,
RTT可能不是固定的,所以RTO对应也不是固定的 - 一般超时重传一次,下一次超时重传的间隔会加倍,避免网络环境差的频繁发送
- 快速重传:
超时重传的问题:重传周期可能很长(时间会加倍),快速重传可以解决这个问题,以数据为驱动作为重传- 发送了数据包
seq1~seq5,- 发送端发送
seq1,接收端回复ack=2,表示接收到包1 seq2丢失- 发送端连续发送
seq3~seq5,接收端会重复返回ack=2 - 连续三次
ack=2,触发快速重传,重复seq2 - 由于接收到了
seq3~seq5,发送端会返回ack=6
- 发送端发送
- 快速重传只解决了超时问题,但是还有一个问题:重传的时候重传一个还是所有数据包
- 因为如果只重传一个,当有两个数据包丢失的时候,需要判断两次返回的ack(三次重复),来进行单包重传,效率低
- 如果重传所有,就会有多余的包被重新发送,无用功
- SACK:选择性确认,可以知道哪些数据丢失了
- 需要
TCP头部选项字段中,添加一个SACK,可以将已接收到的数据的信息发送给发送方,发送方就知道了哪些数据丢失了,从而只发送丢失的数据 - 在快速重传的基础上,发送方收到三次相同的ack报文,触发快速重传机制,通过
SACK信息可以知道哪段数据丢失了,只对丢失的数据重传
- 需要
D-SACK:通过SACK告诉发送端哪些数据被重复接收了- 可以让发送端知道是包丢失,还是ACK包丢失了
- 可以知道发送的数据包是不是被网络延迟了
- 可以知道网络中是不是把发送端的数据包给复制了
- 小结:
- 如果数据包丢失或者ACK包丢失,超过一定时间会触发超时重传,超时时间
RTO略大于RTT时间(发送数据到接收ACK包的时间间隔) - 为了解决超时等待的时间,提高效率,就有了快速重传,当有一个包丢失的时候,可以通过判断重复的ack进行快速重传,通过在TCP头部的选项字段里面添加SACK,就可以知道哪些包是丢失的,从而只重传丢失的包
- 如果在
ACK包丢失,导致的超时重传,发送端接收到接收端SACK从而知道收到了重复数据,这个SACK就是D-SACK,如果一个包由于网络问题导致的快速重传,也可以通过D-SACK来进行判断
- 如果数据包丢失或者ACK包丢失,超过一定时间会触发超时重传,超时时间
2、TCP滑动窗口
TCP每次发送数据都要进行确认应答,当上一个包收到应答了再发下一个
- 如果是一问一答的形式,则数据包往返的时间周期越长,通信效率就越低
- 为了解决上面的问题,就有窗口概念,
- 可以指定窗口大小,窗口大小是不需要等待确认应答,可以继续发送数据的最大值
- 窗口是内核里面开辟的缓存区,需要保留发送的数据,只有收到应答才会从缓冲区中删除
- 在
TCP头部可以指定窗口大小,发送端会根据ACK返回的窗口大小,来发送数据,从而保证对端可以正常接收数据,所以窗口大小是由接收端决定的
- 发送端的窗口:
- 有两个绝对指针:一个指向没有收到ack的第一个字节的序列号, 一个指向窗口中可用空间的第一个字节的序列号
- 会根据ACK报文中的窗口大小进行调整,因为应用层不一定及时收数据
- 此外,如果发送端窗口满了,没有及时收到
ACK,就不能在应用层进行发送数据,如果序列号较前的收到ack,窗口会向右移动,存在可发空间,应用层可以继续拷贝发送数据
- 接收端的窗口:可以接收发送端发送的数据量,一次能处理的数据量
- 只有一个绝对指针,指向期望对端发送来的下一个字节的序列号
- 窗口里面是还没进行确认的数据,也就是还没收到的数据,但是可以接收的数据大小
- 发送端窗口约等于接收端窗口,因为传输存在延迟,不一定及时调整窗口大小,所以是约等于
- 小结:
- 三次握手确定窗口大小,接收端能接收多少数据,发送端根据接收端数据进行调整,去发送数据,在发送端窗口大小内,发送端可以一直发,并等待接收端返回ack确认号来发送窗口移动,每次ack报文都会携带窗口大小,可能会改变;
3、TCP流量控制
利用滑动窗口实现流量控制,发送端不能一股脑的发过去,如果对方处理不过来就会触发重传机制
- 流量控制:发送方 根据 接收方的实际接收能力发送数据,也就是接收端滑动窗口的大小
- TCP内核缓冲区和滑动窗口的关系:缓冲区大小会影响窗口大小
- 应用层不及时收取数据,会导致窗口变小:
- TCP滑动窗口(指针实现)是处于TCP缓冲区中间的,如果接收端接收到数据并返回ACK,但是应用层没有及时收取,当缓冲区内存不够,可能会导致滑动窗口变小,当窗口大小变成0,就发生了窗口关闭
- 系统资源减少,会导致缓冲区变小:
- 如果用户空间没有及时读取缓冲区数据,并且接收缓冲区由于系统资源突然变小,发送端来不及调整,会导致数据丢包现象,这是因为先减少缓冲区再收缩窗口
- 所以不允许同时减少缓冲又收缩窗口,而先收缩窗口后一段时间再减少缓冲,从而避免丢包
- 应用层不及时收取数据,会导致窗口变小:
- 窗口关闭:
- 窗口大小为0的情况,就会阻止发送端发送数据,直到大小变成非0
- 如果接收端窗口变成非0,会通过发送携带窗口大小的ACK报文,如果ACK报文丢失,发送端会一直等待,造成死锁问题
- 如何避免死锁问题:当窗口关闭,就会启动一个持续计时器,如果超时就会发送一个
窗口探测报文,接收端收到这个报文,就会返回一个携带当前窗口大小的ACK报文,如果窗口依旧为0,就会重启持续计时器
- 糊涂窗口综合症
- 接收端太忙,会导致发送端的窗口越来越小,到最后只有接收端腾出字节空间,发送端就会马上发送,但是TCP/IP包头就有40字节,有数据就传输的话,开销太大了
- 导致的原因是:
- 接收端告知小窗口大小
- 发送端发送小数据
- 如何避免:
- 接收方不告知小窗口,窗口小于某个值就发送窗口为0的ACK,阻止对端发送数据
- 发送发避免发送小数据,开启Nagle算法,避免小包发送
- Nagle算法思想,延时处理,满足下面一个条件即可:
- 窗口大小>=MSS并且数据大小>=MSS
- 收到前一个数据的ack报文
- 一般需要搭配 不通知小窗口给发送方+开启Nagle算法才能避免糊涂窗口综合症
4、TCP拥塞控制
-
流量控制:是为了避免,发送端 数据填满 接收端的缓存,但是流量控制并不知道网络中发送的情况
-
网络拥塞:网络发生拥堵的时候,继续发送大量数据包,就可能导致数据包延时、丢失等情况,TCP就会重传数据,一旦重传就会导致网络更加拥堵,从而不断恶性循环
-
拥塞控制:避免发送方的数据填满整个网络,并且为了调节发送数据的量,定义了一个
拥塞窗口(cwnd)的概念 -
拥塞窗口(cwnd):是发送方维护的一个状态变量,会根据网络的拥塞程度进行变化,滑动的发送窗口=min(滑动的接收窗口,拥塞窗口),当网络没有出现拥塞,
cwnd窗口就会越大,当网络出现拥塞,cwnd就会越小 -
如何判断网络拥塞:发送方没有在指定时间接收到ACK应答报文,也就是发送超时重传,就会认为网络出现拥塞了
-
拥塞控制主要是四算法:
- 慢启动:(指数增长)
- TCP建立连接后,一点点点提高数据包发送的数量,发送端没收到一个ACK,拥塞窗口
cwnd的大小就会+1; - 存在一个慢启动门限
ssthresh,如果cwnd<ssthresh使用的就是慢启动算法,如果cwnd>=ssthresh,就使用拥塞避免算法;ssthresh一般大小为65535字节
- TCP建立连接后,一点点点提高数据包发送的数量,发送端没收到一个ACK,拥塞窗口
- 拥塞避免:
- 没收到一个ACK,
cwnd增加1/cwnd,是为了确保cwnd的线性增长 - 如果一直保持增长,网络就会慢慢进入拥塞状态,从而出现了丢包现象
- 如果触发了重传机制,就会进入拥塞发生算法
- 没收到一个ACK,
- 拥塞发送:
- 发生重传(超时、快速)的时候就会进入拥塞发生算法
- 超时重传的拥塞发生:
ssthresh会设置为cwnd/2,并且cwnd会回复为初始值,linux的初始值是10(10个MSS);- 设置完
ssthresh和cwnd之后,会重新开始慢启动; - 这种方式下来的拥塞发生太激进了,容易造成网络卡顿
- 快速重传的拥塞发生:
- 设置
cwnd为cwnd/2,再设置ssthresh为cwnd - 设置完之后,会进入
快速回复算法
- 设置
- 快速回复:
- 当发生快速重传的时候,表示网络不是太糟糕,一般快速回复和快速重传同时使用
- 进入快速回复前,
cwnd和ssthresh都全部设置完了 快速回复:cwnd=ssthresh+3,3表示接收到了三个数据包- 重传丢失的数据包;
- 如果再收到重复的
ACK,cwnd就+1 - 如果收到的是新的ACK,表示网络没问题了,则将cwnd设置为ssthresh,进入拥塞避免状态;
- 慢启动:(指数增长)
-
拥塞控制算法过程:
- 从TCP三次握手建立连接开始,发送端开始慢启动,没收到一个包的ACK,拥塞窗口就会+1,如果达到阈值,就会进入拥塞避免算法,每收到一个包的ACK,拥塞窗口就会增加窗口的倒数,从而保证拥塞窗口的线性增加
- 当遇到丢包的情况,就判断为网络拥塞,从而重复重传机制,进入拥塞发送算法,根据重传机制的不同,拥塞发送算法也会不同
- 超时重传,sthresh=cwnd/2,并且cwnd=初始值,重新重慢启动开始
- 快速重传,cwnd=cwnd/2,ssthresh=cwnd,开启快速回复
- 快速回复:先是设置cwnd=ssthresh+3,并重传丢失数据包,如果依旧重复收到相同的ACK,就会重复触发快速重传和快速回复,如果收到的是新的数据包,则进入拥塞避免状态。
参考文章:小林coding
相关文章:
网络编程(12): TCP重传、滑动窗口、流量控制、拥塞控制
1、TCP重传机制 通过序列号和确认号确保可靠传输,当发送端发送数据给接收到,接收端会返回一个确认号,表示收到消息了 超时重传:没有在指定时间内收到ACK报文 超时重传的两种可能:数据包丢失、确认包丢失超时重传时间RT…...
Docker安装RabbitMQ服务端
使用docker安装RabbitMQ服务端 1、搜索镜像 docker search rabbitmq2、拉取镜像 默认拉取最后一个版本,可以在后面加版本号拉取指定版本 docker pull rabbitmq 3、运行镜像 docker run -d --hostname my-rabbit --name rabbit -p 15672:15672 rabbitmq4、查看…...
vueuse常用方法
useDateFormat 时间格式化 <script setup lang"ts">import { useNow, useDateFormat } from vueuse/coreconst formatted useDateFormat(useNow(), YYYY-MM-DD HH:mm:ss)</script><template><div>{{ formatted }}</div> </templa…...
选择大型语言模型自定义技术
推荐:使用 NSDT场景编辑器 助你快速搭建可二次编辑器的3D应用场景 企业需要自定义模型来根据其特定用例和领域知识定制语言处理功能。自定义LLM使企业能够在特定的行业或组织环境中更高效,更准确地生成和理解文本。 自定义模型使企业能够创建符合其品牌…...
算法概述-Java常用算法
算法概述-Java常用算法 1、算法概念2、算法相关概念3、算法的性能评价4、算法应用归纳 1、算法概念 广泛算法定义:算法是模型分析的一组可行性的、确定的和有穷的规则。 经典算法特征:有穷性、确切性、输入、输出和可行性。 常用的算法包括递推、递归、穷…...
CCLINK转MODBUS-TCP网关cclink通讯接线图 终端电阻
大家好,今天我们要聊的是生产管理系统中的CCLINK和MODBUS-TCP协议,它们的不同使得数据互通比较困难,但捷米JM-CCLK-TCP网关的出现改变了这一切。 1捷米JM-CCLK-TCP是一款自主研发的CCLINK从站功能的通讯网关,它的主要功能是将各种…...
香蕉派 BPI-P2 Pro采用RK3308芯片,512M内存,8G存储,支持PoE供电
Banana Pi BPI-P2 pro(Armsom pro)是一款基于瑞芯瑞(Rockchip) RK3308B-S芯片的开发板。采用高性能4核ARM Cortex-A35处理器,512M RAM内存。和8G eMMC板载存储,支持PoE网线供电功能。芯片具有丰富的接口,如I2S、PCM、TDM、I2C、UART、SPDIF、…...
「隐语小课」拆分学习之“水平拆分学习”
一、引言 拆分学习是 2018 年由 MIT 最先提出的分布式算法。本文结合该领域的相关英文文献,介绍水平拆分学习的基本方法,同时还将对比拆分模型与中心化模型、联邦模型在不同条件下模型效率和准确性。拆分学习作为主流的隐私计算学习范式之一,…...
WPF--关于Action事件小结
WPF--关于Action事件小结 1.需要类实例去调用事件建立订阅关系 public event Action<int, object> MaintainEvent; new GP1().MaintainEvent NormalCmdAction; 2.static用处--在不便实例的时候,可以直接由类调用 public static event Action<int, objec…...
创建一个 React+Typescript 项目
接下来 我们来一起探索一下用TypeScript 来编写react 这也是一个非常好的趋势,目前也非常多人使用 那么 我们就先从创建项目开始 首先 我们先找一个 或者 之前创建一个目录 用来放我们的项目 然后 在这个目录下直接输入 例如 这里 我想创建一个叫 tsReApp 的项目…...
Java课题笔记~ 数据提交的方式
前四种数据注入的方式,会自动进行类型转换。但无法自动转换日期类型。 (1)单个数据(基本数据类型)注入 在方法中声明一个和表单提交的参数名称相同的参数,由框架按照名称直接注入。 (2&#x…...
VUE3给页面添加按钮事件
在Vue 3中,可以通过使用setup函数来添加事件和自定义逻辑。下面是一个示例代码,演示了如何添加页面上的altb事件 <template><div><p>Press Alt B to trigger the event!</p></div> </template><script setup&g…...
基于centos7.9通过nginx实现负载均衡以及反向代理
摘要:负载均衡: 负载均衡是一种技术,用于在多个服务器之间分发传入的网络流量,以平衡服务器的负载,提高系统的可用性和性能。当您有多台服务器时,您可以使用负载均衡将请求分发到这些服务器上,从…...
前端原生写自定义旋转变换轮播图
html部分: <div class"banner_box"><div class"swiperWrapper" v-show"bannerList.length>0"><div class"swiper-item" :id"swiperSlide${index}" :class"{active:index0,next:index1,pr…...
linux tomcat server.xml 项目访问路径变更不生效
如果想改成默认的127.0.0.1:8080 访问项目 先确定更改的作用文件 server.xml 的 host:appBase 标签 默认找到appBase webapps 下的war包,并解压,解压后的appname为访问路径 也就变成了 127.0.0.1:8080/appname host:Context:path 标签 appBase的 优先…...
介绍原型模式:快速构建和复制对象的设计模式
经过瀑布模式之后,我们不禁想要用模型解决更多的问题,最重要的就是不再单向行径。 由此,介绍 原型模式, 所谓原型,就是我们有一个框架或者初始角色。我们可以根据项目的不同,对它进行不同的修改࿰…...
Unity的TimeScale的影响范围分析
大家好,我是阿赵。 这期来说一下Unity的TimeScale。 一、前言 Unity提供了Time这个类,来控制时间。其实我自己倒是很少使用这个Time,因为做网络同步的游戏,一般是需要同步服务器时间,所以我比较多是在使用System.Date…...
爬虫逆向实战(五)--猿人学第三题
一、数据接口分析 主页地址:猿人学第三题 1、抓包 通过抓包可以发现数据接口是api/match/3 2、判断是否有加密参数 请求参数是否加密? 无请求头是否加密? 无响应是否加密? 无cookie是否加密? 无 二、发送请求 …...
[虚幻引擎] UE使用虚拟纹理在模型上显示挖空效果
此教程是记录如在UE中使用虚拟纹理,实现模型挖洞的效果。 1. 新建项目,开启项目支持虚拟纹理并并重启。 2. 新建一个基础关卡 3. 拖动“运行时虚拟纹理体积” 进入场景,并把体积修改变大,以可以完全包括到地板。 4. 创建一个虚拟纹…...
vue3中reactive和ref的比较
1.reactive和ref函数的共同作用是什么? 用函数调用的方式生成响应式数据 2. reactive vs ref? 1.reactive不能处理简单类型的数据 2.ref参数类型支持更好但是必须通过.value访问修改 3.ref函数的内部实现依赖于reactive函数 3. 在实际工作中推荐使用哪个? …...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
