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

TCP重传机制、滑动窗口、拥塞控制

一、总述

TCP,Transmission Control Protocol,是一个面向连接、基于流式传输可靠传输协议,考虑到的内容很多,比如数据包的丢失、损坏、分片和乱序等,TCP协议通过多种不同的机制来实现可靠传输。今天,重点分析重传机制滑动窗口,以及拥塞控制

二、重传机制

在三握四挥的过程中,服务器和客户端之间就通过带有不同标志位的TCP报文来通知或判断对端或本地是否成功建立、断开连接。

接收主机在接收到数据之后往往都会返回一个应答消息,网络错综复杂,面对随时可能发生的数据丢失问题,TCP使用重传机制解决。常见的重传机制有以下四种:

  • 超时重传
  • 快速重传
  • SACK
  • D_SACK
(一) 超时重传

超时重传,顾名思义,在发送数据时,会设定一个定时器,当超过指定的时间过后,没有收到对端的ACK确认应答报文,就会重写发送该数据。而这又可以分为两种情况:

  • 数据包丢失
  • ACK确认应答丢失

在了解如何设置超时时间之前,先来看看什么是RTT(Round-Trip Time)往返时延

RTT,往返时延,数据从一端到另一端。其中,往返这个词是表明了什么范围是所需的时间。

知道了RTT,在来看点相关的:RTO,Retransmission Timeout,直译“超时重传时间”。这个时间的设置毫无疑问关系到我们重传机制的效率高低,看以下两种情况:

  • RTO>>RTT,重发慢,没有效率;
  • RTO<<RTT,包可能还没到就开始重发,重发出去的包数量多了,网络无疑会拥塞,超时的包越来越多,恶性循环。

那么结论显而易见——RTO的值,应该略大于RTT

很容易想到的是,报文往返的RTT值会是经常变化的,所以RTO也应该是一个动态变化的值。(在Linux中,通常会采样RTT的值然后加权算平均,不详细谈了)

而在超时时,TCP的策略是超时间隔加倍

(二) 快速重传

Fast Retransmit,快速重传,不以时间为驱动,而以数据驱动重传

在上图中,Seq2一直没有成功被接收方收到,当发送端收到三个Ack=2的确认,就会在定时器过期之前,重传丢失的Seq2

不过,发送方并不知道Ack=2是谁传回来的,那么是重传Seq2还是把之前的所有包都重传呢?根据TCP实现的不同,上述两种情况都是可能的。

(三) SACK

SACK是指Selective Acknowledgment,选择性确认,这种方式通过在TCP头部"选项"字段添加一个SACK,把缓存的地图发送给发送方,这样发送方就知道哪些数据需要重传了。


如果要支持SACK,双方都要支持,在Linux下,通过net.ipv4.tcp_sack这个参数打开(Linux2.4后默认打开)。

(四) Duplicate SACK

D_SACK,主要使用SACK来通知发送方有哪些数据被重复接收了,下面通过两个例子来说明,这个Duplicate到底有什么妙用。

  • ACK丢包

发送端通过ACK和SACK就可以明确,是发出去的包丢了还是接收方返回的ACK确认报文丢了

  • 网络延时

在判定网络延迟时,Duplicate的含义才更加明显地体现了出来,即复制的、完全一样的。

如上图中提及,在经历了网络延迟和三次相同ACK触发快速重传后,网络延迟的包终于送达,此时返回ACK=3000,SACK=1000~1500(注意之前的SACK范围总是大于ACK),就知道了这个SACK是D_SACK,是重复的包。

三、滑动窗口(流量控制)

(一) 滑动窗口

滑动窗口,Sliding Window,是一种流量控制机制,同时也是一种保持通信效率的技术。已知的是,每当有一个数据包发出,发送端总盼望得到一个ACK确认;那么要是在得到ACK之前不做任何动作,效率的高低明显可见。

为此,TCP引入了窗口的概念,通过指定窗口大小(数据最大值),来进行无需等待确认应答的通信

在实际实现时,是由操作系统开辟一个缓存空间。在发送方得到确认应答前,已发送的数据都会保存在缓冲区,如果按期收到确认应答,此时数据就可以从缓冲区清除。

如此一来,有了累计确认(或累计应答)模式:

  • 那么引申出一个问题——窗口的大小由哪一方决定?

TCP报头中有一个16位的字段:窗口尺寸Window,这个字段是由接收方通知发送方自己还有多少缓冲区可以用来接收数据。以免接收方无法正常接收到数据。

  • 发送方,滑动窗口分为4个部分

它的工作方式很容易想到:ACK确认一部分,可用窗口就扩大一部分;当发送窗口满了,在接收ACK之前就不再发送数据。

  • 接收方,滑动窗口分为3个部分

值得注意的是,两个窗口的大小是约等于的关系,而不是一模一样。因为滑动窗口不是一成不变的。如果接收方的读取速度有了很大提升,会通过TCP报文通知发送方新的窗口大小。

(二) 窗口关闭问题

TCP中,通过接收方指定窗口尺寸来进行流量控制。在通信中,当接收方窗口被填满,会向发送方说明窗口尺寸位0;等处理好数据后,才会又通告一个窗口非0的ACK报文。不过,要是这个非0报文丢失,就会陷入死锁的状态(双方同时等待)。

  • 窗口探测报文

为了解决这个问题,TCP为每个连接设置了一个持续计时器,只要收到0窗口通告,就启动计时器。当计时器超时,就会发送窗口探测报文,这个报文的用意显而易见。(窗口探测的次数一般是3次)。

(三) 糊涂窗口问题

糊涂窗口是指接收方在处理数据时的速度过慢,导致窗口的尺寸不断变小的现象。实际上就是两个动作让这个现象出现:

  • 接收方通告小窗口
  • 发送方发送小数据

想要避免这种现象,解决上述两个问题就好了。

  1. 在接收方,当窗口小于min(MSS, 缓存空间/2),就会告知对方0窗口,到后面合适的时机再通知非0窗口。
  2. 在发送方,使用Nagle算法进行延时处理,要等到发送窗口大小>=MSS,或者接收到ACK确认报文,才会停止囤积数据。这个算法是默认打开的,在使用telnet和ssh等交互性比较强的程序时,通过TCP_NODELAY来关闭。

四、拥塞控制

(一) 什么是拥塞

上文的流量控制是避免发送方的数据填满接收方的缓存,而拥塞控制,则是为了避免在整个网络环境处于拥堵时,还继续发送大量数据包的手段(可能导致数据包时延、丢失等,重传也会加重拥塞)。

那么很明显,拥塞控制是在发送端实现的。为了调节发送数据的量,定义了“拥塞窗口”的概念。

(二) 什么是拥塞窗口

拥塞窗口,是一个由发送方维护的状态变量,根据网络的拥塞程度动态变化。前面的发送窗口和接收窗口在有了拥塞窗口的加入以后,是这样的关系:

  • 发送=min(拥塞,接收)

拥塞窗口的动态变化也很简答:有拥塞,就变小;没拥塞,就变大。

(三) 如何判断拥塞

只要发送方没在规定的时间内接收到ACK确认报文(发生超时重传),就会认为网络出现了拥塞。

(四) 拥塞控制算法——慢启动

TCP在刚建立完连接后,会经历慢启动,逐步提高发送数据包的数量。规则是:

  • 发送方每收一个ACK,拥塞窗口cwnd的大小就增加1。

所以,这个增长是指数性的

那什么时候是个头呢?——当达到慢启动门限(slow start threshold)后,就会使用拥塞避免算法

(五) 拥塞避免算法

慢启动门限ssthresh一般的大小为65535字节,在进入拥塞避免算法后,窗口增长的规则是:

  • 每当收到一个ACK,cwnd增加1/cwnd。

如此一来,线性增长

在此后一直增长,网络就会进入拥塞的状态,出现丢包和丢包重传,触发了重传,也就进入了拥塞发生算法

(六) 拥塞发生

在上文提到过,重传的机制也有两种:1. 超时重传,2. 快速重传。接下来进行分述:

  • 超时重传的拥塞发生算法

ssthresh设置为cwnd/2,cwnd重置为1,然后重新开始慢启动。不过这种方式会突然减少数据流,可能网络卡顿(就像是急刹车)。

  • 快速重传的拥塞发生算法

在快速重传时,接收方发送三次前一个包的ACK通知发送端重传(大部分没丢,只丢了小部分)。

cwnd=cwnd/2,ssthresh=cwnd,然后进入快速恢复算法

(七) 快速恢复

快速重传一般和快速恢复算法同时使用,这种情况会判断网络情况并不是特别严峻,反映也不会像RTO那样强烈。

快速恢复算法

  • cwnd=ssthresh+3
  • 重传丢失的数据包
  • 如果再收到重复的ACK,cwnd+1
  • 如果收到新ACK(说明D_SACK时的数据全部收到,恢复过程结束),cwnd=ssthresh,恢复到之前二点拥塞避免状态

本文作为笔记,图片来源:

30 张图解: 面试必问的 TCP 重传、滑动窗口、流量控制、拥塞控制_面试回答 tcp流量控制-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_34827674/article/details/105606205

相关文章:

TCP重传机制、滑动窗口、拥塞控制

一、总述 TCP&#xff0c;Transmission Control Protocol&#xff0c;是一个面向连接、基于流式传输的可靠传输协议&#xff0c;考虑到的内容很多&#xff0c;比如数据包的丢失、损坏、分片和乱序等&#xff0c;TCP协议通过多种不同的机制来实现可靠传输。今天&#xff0c;重点…...

electron+vue3全家桶+vite项目搭建【29】封装窗口工具类【3】控制窗口定向移动

文章目录 引入实现效果思路声明通用的定位对象主进程模块渲染进程测试效果 引入 demo项目地址 窗口工具类系列文章&#xff1a; 封装窗口工具类【1】雏形 封装窗口工具类【2】窗口组&#xff0c;维护窗口关系 封装窗口工具类【3】控制窗口定向移动 很多时候&#xff0c;我们想…...

深入了解304缓存原理:提升网站性能与加载速度

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

python-批量操作excel

批量新增excel文件 import osimport xlwings as xwapp xw.App(visibleTrue,add_bookFalse)#visible设置为ture的时候会自动打开创建的excel文件&#xff0c;设为为false的时候不会看到excel文件打开了&#xff0c;实际进程占用了....dept_list [人事部,财务部,研发部,行政部…...

#QT(串口助手-界面)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;编写串口助手 3.记录 接收框:Plain Text Edit 属性选择&#xff1a;Combo Box 发送框:Line Edit 广告&#xff1a;Group Box &#xff08;1&#xff09;仿照现有串口助手设计UI界面 &#xff08;2&#xff09;此时串口助手大…...

C语言进阶——位段

在C语言中&#xff0c;位段&#xff08;Bit Fields&#xff09;是一种用来对结构体中的成员进行位级别的控制的特性。通过位段&#xff0c;我们可以灵活地控制结构体中各个成员的位数&#xff0c;从而节省内存空间并提高程序的效率。本篇博客将详细讲解C语言中位段的相关知识&a…...

软件设计师软考题目解析23 --每日五题

想说的话&#xff1a;要准备软考了。0.0&#xff0c;其实我是不想考的&#xff0c;但是吧&#xff0c;由于本人已经学完所有知识了&#xff0c;只是被学校的课程给锁在那里了&#xff0c;不然早找工作去了。寻思着反正也无聊&#xff0c;就考个证玩玩。 本人github地址&#xf…...

总结:前后端集合、数组类型数据交互底层原理,SpringBoot框架解析

总结&#xff1a;前后端集合、数组类型数据交互底层原理&#xff0c;SpringBoot框架解析 一前后端信息交互本质&#xff1a;1.两台电脑可以通过收发电磁波、控制网线电路开关等基础物理设施&#xff0c;就可以进行物理层面的电信号交互&#xff0c;电信号又可以通过各种传感设备…...

2024蓝桥杯每日一题(前缀和)

一、第一题&#xff1a;壁画 解题思路&#xff1a;前缀和贪心枚举 仔细思考可以发现B值最大的情况是一段连续的长度为n/2上取整的序列的累加和 【Python程序代码】 import math T int(input()) for _ in range(1,1T):n int(input())s input()l math.ceil(len(s)/…...

2007-2022年上市公司迪博内部控制评价缺陷数量数据

2007-2022年上市公司迪博内部控制评价缺陷数量数据 1、时间&#xff1a;2007-2022年 2、范围&#xff1a;上市公司 3、指标&#xff1a;证券代码、证券简称、辖区、证监会行业、申万行业、是否存在财报内控重大缺陷、财报内控重大缺陷数量、是否存在财报内控重要缺陷、财报内…...

JAVA虚拟机实战篇之内存调优[4](内存溢出问题案例)

文章目录 版权声明修复问题内存溢出问题分类 分页查询文章接口的内存溢出问题背景解决思路问题根源解决思路 Mybatis导致的内存溢出问题背景问题根源解决思路 导出大文件内存溢出问题背景问题根源解决思路 ThreadLocal占用大量内存问题背景问题根源解决思路 文章内容审核接口的…...

qt自定义时间选择控件窗口

效果如图&#xff1a; 布局如图&#xff1a; 参考代码&#xff1a; //DateTimeSelectWidget #ifndef DATETIMESELECTWIDGET_H #define DATETIMESELECTWIDGET_H#include <QWidget> #include <QDateTime>namespace Ui { class DateTimeSelectWidget; }class DateTim…...

如何不解压直接读取gzip文件里面的文件

要在服务器上不解压缩的情况下读取gzip文件中的文件内容&#xff0c;您可以使用类似于zlib模块的库&#xff0c;这些库允许您在内存中对gzip数据进行操作而无需解压缩到磁盘上的文件。 在Python中&#xff0c;您可以使用gzip模块来实现这一目的。以下是一个示例代码&#xff0…...

python 截取字符串string.split

目录 作用语法只要第一个值获得第3个值遍历 作用 根据某个符号对数据进行截取 从而获得自己想要的内容 语法 使用’string.split’ 方法 对字符串’123/abc/BPYC’ 以 ‘/’ 进行截取 string "123/abc/BPYC" substring string.split("/") print(subs…...

SpringBoot+Vue实现el-table表头筛选排序(附源码)

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;在笑大学牲 &#x1f39f;️个人主页&#xff1a;无所谓^_^ ps&#xff1a;点赞是免费的&#xff0c;却可以让写博客的作者开心好几天&#x1f60e; 前言 后台系统对table组件的需求是最常见的&#xff0c;不过element-ui的el…...

Linux学习之线程

目录 线程概念 1.什么是线程&#xff1f; 2.线程的优缺点 3.线程异常 4.线程用途 线程操作 1.如何给线程传参 2.线程终止 3.获取返回值 4.分离状态 5.退出线程 线程的用户级地址空间&#xff1a; 线程的局部存储 线程的同步与互斥 互斥量mutex 数据不一致的主要过…...

【JavaEE初阶】 JVM类加载简介

文章目录 &#x1f343;前言&#x1f332;类加载过程&#x1f6a9;加载&#x1f6a9;验证&#x1f6a9;准备&#x1f6a9;解析&#x1f6a9;初始化 &#x1f384;双亲委派模型&#x1f6a9;什么是双亲委派模型&#xff1f;&#x1f6a9;双亲委派模型的优点 ⭕总结 &#x1f343…...

.NET Core依赖注入(IoC)不使用构造函数实现注入

在.NET Core中&#xff0c;依赖注入&#xff08;IoC&#xff09;通常是通过构造函数注入来实现的&#xff0c;这是推荐的方式&#xff0c;因为它使得依赖关系更加明确和可测试。但是&#xff0c;如果你不想或不能使用构造函数注入&#xff0c;你可以考虑使用方法注入&#xff0…...

WinSCP下载安装并结合内网穿透实现固定公网TCP地址访问本地服务器

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件&#xff0c;它的主要功能是在本地与远程计…...

内联函数|auto关键字|范围for的语法|指针空值

文章目录 一、内联函数1.1概念1.2特性 二、auto关键字2.2类型别名思考2.3auto简介2.4auto使用细则2.4 auto不能推导的场景 三、基于范围的for循环(C11)3.1 范围for的语法 四、指针空值nullptr(C11)4.1 C98中的指针空值 所属专栏:C初阶 一、内联函数 1.1概念 以inline修饰的函…...

JavaSec-RCE

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

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...