首页 > 其他分享 >TCP可靠机制详解

TCP可靠机制详解

时间:2024-11-24 12:13:39浏览次数:7  
标签:窗口 重传 报文 TCP 可靠 发送 拥塞 cwnd 详解

重传机制

针对数据包丢失的情况,会用重传机制解决。

超时重传

在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的ACK 确认应答报文,就会重发该数据,也就是我们常说的超时重传。TCP 会在以下两种情况发生超时重传:数据包丢失,确认应答丢失

缺点:

  • 当超时时间 RTO 较大时,重发就慢,丢了老半天才重发,没有效率,性能差;

  • 当超时时间 RTO 较小时,会导致可能并没有丢就重发,于是重发的就快,会增加网络拥塞,导致更多的超时,更多的超时导致更多的重发。

所以超时重传时间 RTO 的值应该略大于报文往返 RTT 的值。

快速重传

TCP 还有另外一种快速重传(Fast Retransmit)机制,它不以时间为驱动,而是以数据驱动重传

假设发送方发出了 1,2,3,4,5 份数据,但是第二个数据丢失,1,3,4,5到了接收端只会回复ack=2,当3,4,5都到达后,发送者会收到3个ack=2的确认,知道了 Seq2 还没有收到,就会在定时器过期之前,重传丢失的 Seq2。

但是它依然面临着另外一个问题。就是重传的时候,是重传一个,还是重传所有的问题。

举个例子,假设发送方发了 6 个数据,编号的顺序是 Seq1 ~ Seq6 ,但是 Seq2、Seq3 都丢失了,那么接收方在收到 Seq4、Seq5、Seq6 时,都是回复 ACK2 给发送方,但是发送方并不清楚这连续的 ACK2 是接收方收到哪个报文而回复的, 那是选择重传 Seq2 一个报文,还是重传 Seq2 之后已发送的所有报文呢。

  • 如果只选择重传 Seq2 一个报文,那么重传的效率很低。因为对于丢失的 Seq3 报文,还得在后续收到三个重复的 ACK3 才能触发重传。
  • 如果选择重传 Seq2 之后已发送的所有报文,虽然能同时重传已丢失的 Seq2 和 Seq3 报文,但是 Seq4、Seq5、Seq6 的报文是已经被接收过了,对于重传 Seq4 ~Seq6 折部分数据相当于做了一次无用功,浪费资源。

SACK选择性确认

这种方式需要在 TCP 头部「选项」字段里加一个 SACK 的东西,它可以将已收到的数据的信息发送给「发送方」,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据

滑动窗口

为什么引入窗口

TCP 是每发送一个数据,都要进行一次确认应答。当上一个数据包收到了应答了, 再发送下一个。但这种方式的缺点是效率比较低的。为解决这个问题,TCP 引入了窗口这个概念。

原理

假设窗口大小为 3 个 TCP 段,那么发送方就可以「连续发送」 3 个 TCP 段,并且中途若有 ACK 丢失,可以通过「下一个确认应答进行确认」。意味着 所有数据「接收方」都收到了。这个模式就叫累计确认或者累计应答

窗口大小谁决定

TCP 头里有一个字段叫 Window,也就是窗口大小。这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。所以,通常窗口的大小是由接收方的窗口大小来决定的。

发送方:

image-20241116103031193

接收方:

image-20241116103057258

流量控制

操作系统与滑动窗口的关系

  • 当应用程序没有及时读取缓存时:假设客户端与服务端在进行正常数据发收,但是服务端非常繁忙,每次应用进程只读取了部分字节,于是就有剩余的字节占着缓冲区,于是窗口就会收缩,当进行多次这种情况后,窗口最后会变为0,也就是发生了窗口关闭。

  • 当服务端系统资源紧张时,操作系统可能会直接减少了接收缓冲区大小:服务端因繁忙,操作系统就把接收缓存减少字节。这时应用程序又无法及时读取缓存数据,那么这时候就有严重的事情发生了,会出现数据包丢失的现象。

为了防止这种情况发生,TCP 规定是不允许同时减少缓存又收缩窗口的,而是采用先收缩窗口,过段时间再减少缓存,这样就可以避免了丢包情况。

窗口关闭

如果窗口大小为 0 时,就会阻止发送方给接收方传递数据,直到窗口变为非 0 为止,这就是窗口关闭。

当发生窗口关闭时,接收方处理完数据后,会向发送方通告一个窗口非 0 的 ACK 报文,如果这个通告窗口的 ACK 报文在网络中丢失了,那麻烦就大了。这会导致发送方一直等待接收方的非 0 窗口通知,接收方也一直等待发送方的数据,造成了死锁的现象。

为了解决这个问题,TCP 为每个连接设有一个持续定时器,只要 TCP 连接一方收到对方的零窗口通知,就启动持续计时器。

如果持续计时器超时,就会发送窗口探测 ( Window probe ) 报文,而对方在确认这个探测报文时,给出自己现在的接收窗口大小。

拥塞控制

在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包时延、丢失等,这时 TCP 就会重传数据,但是一重传就会导致网络的负担更重,于是会导致更大的延迟以及更多的丢包

于是,就有了拥塞控制,控制的目的就是避免「发送方」的数据填满整个网络。又引入了拥塞窗口的概念

拥塞窗口 cwnd是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的

  • 只要网络中没有出现拥塞,cwnd 就会增大;
  • 但网络中出现了拥塞,cwnd 就减少;

那么怎么知道当前网络是否出现了拥塞呢?

其实只要「发送方」没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了拥塞。

慢启动

慢启动的算法记住一个规则就行,当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1。

增加到什么时候:

慢启动门限 ssthresh (slow start threshold)状态变量。

  • cwnd < ssthresh 时,使用慢启动算法。
  • cwnd >= ssthresh 时,就会使用「拥塞避免算法」

拥塞避免

进入拥塞避免算法后,它的规则是:每当收到一个 ACK 时,cwnd 增加 1/cwnd。

也就是说拥塞窗口的增长速度从指数增长变成线性增长,就这么一直增长着后,网络就会慢慢进入了拥塞的状况了,于是就会出现丢包现象,这时就需要对丢失的数据包进行重传。

当触发了重传机制,也就进入了「拥塞发生算法」。

拥塞发生算法

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

这个时候,ssthresh 和 cwnd 的值会发生变化:

  • ssthresh 设为 cwnd/2
  • cwnd 重置为 1 (是恢复为 cwnd 初始化值,我这里假定 cwnd 初始化值 1)

接着,就重新开始慢启动,这种方式太激进了,反应也很强烈,会造成网络卡顿。

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

  • cwnd = cwnd/2 ,也就是设置为原来的一半;
  • ssthresh = cwnd;
  • 进入快速恢复算法

快速恢复

快速重传和快速恢复算法一般同时使用

进入快速恢复算法如下:

  • 拥塞窗口 cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了);
  • 重传丢失的数据包;
  • 如果再收到重复的 ACK,那么 cwnd 增加 1;
  • 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,可以回到恢复之前的状态了,也即再次进入拥塞避免状态;

标签:窗口,重传,报文,TCP,可靠,发送,拥塞,cwnd,详解
From: https://www.cnblogs.com/dwinternet/p/18565631

相关文章

  • SpringBoot不用三方框架,怎么动态调度定时任务,ScheduledExecutorService 详解
    文章目录基础版:控制任务启动与停止1.创建定时任务2.配置SpringBoot以启用定时任务支持3.创建控制器来管理定时任务4.处理动态调整任务间隔的问题5.测试你的API进阶版:动态调整任务执行频率1.添加依赖2.创建定时任务服务3.创建控制器来管理定时任务4.配置Spring......
  • Suricata 技术详解
    Suricata并非是黑客工具,而是一款开源的高效网络威胁检测与防御工具,以下为你展开介绍: 功能特性入侵检测与防御:Suricata能够作为网络入侵检测系统(IDS),实时监控网络流量,对可疑活动和入侵行为发出警报。同时,它也可以充当入侵防御系统(IPS),检测到恶意活动和流量后直接进行阻断,有效......
  • 经典战法【均线老鸭头】战法的机构构成,集中模型以及买卖操盘技术,技术要点图文详解
    直接上干货,首先【均线老鸭头】战法的均线构成我们选择5-10-60均线三条。老鸭头名称的由来,这是一个形象的说法,如上图,图中均线系统排列的形态,是不是像一个鸭脑袋?第一段上涨是鸭脖子,股价开始回落处画上一个圆圈,是鸭子的眼睛,第三段启动上涨的位置就是鸭子的嘴巴。整个图形合在一......
  • 读数据质量管理:数据可靠性与数据质量问题解决之道13数据沿袭
    1. 数据沿袭1.1. MyDoom的病毒1.2. 现在,许多团队甚至整个公司都在使用数据,这要求数据管理的方式要更便于合作,同时也更不容许发生错误1.3. 从采用dbt和ApacheAirflow等开源工具来实现数据转换和编排,到使用Snowflake和Databricks等云端数据仓库和数据湖1.4. 数据仪表板和......
  • sqli-labs做题过程详解
    Less-11.判断注入点提示我们输入一个id,因此构造payload为?id=1and1=2页面正常回显,可判断为字符型。接着判断闭合方式,构造payload为?id=1'页面报错,因此可判断闭合方式为单引号。然后我们可以用–+注释掉’,在中间添加我们想要查询的语句2.联合注入1.判断有多少......
  • TCP vs UDP:如何选择适合的网络传输协议?
    在网络通信中,TCP(TransmissionControlProtocol)和UDP(UserDatagramProtocol)是两种非常重要的传输层协议。它们各有特点,适用于不同类型的应用场景。本文将详细探讨TCP和UDP协议的结构、优缺点及应用,帮助您理解如何在不同情况下选择适合的协议。一、什么是TCP和UDP?TCP(传输控......
  • 「Mac玩转仓颉内测版27」基础篇7 - 字符串类型详解
    本篇将介绍Cangjie中的字符串类型,包括字符串的定义、字面量形式、插值表达、常用操作及应用场景,帮助开发者熟练掌握字符串的使用。关键词字符串类型定义字符串字面量插值字符串字符串拼接常用操作一、字符串类型概述在Cangjie中,字符串是一组Unicode字符的集合,用......
  • 「Mac玩转仓颉内测版28」基础篇8 - 元组类型详解
    本篇将介绍Cangjie中的元组类型,包括元组的定义、创建、访问、数据解构以及应用场景,帮助开发者掌握元组类型的使用。关键词元组类型定义元组创建元组访问数据解构应用场景一、元组类型概述在Cangjie中,元组是一种用于存储多种数据类型的集合。与数组不同,元组的每个......
  • 驱动钛丝(SMA)的可靠性设计(7)接触面设计
    【前言】形状记忆合金(Shapememoryalloy,SMA),也叫形态记忆合金、钛镍记忆合金,它是由Ti(钛)-Ni(镍)材料组成,经过多道工序制成的丝,我们简称钛丝,可以通过电路驱动钛丝发生运动。相比于传统的电机、电磁铁动力,钛丝是一种新型的动力元件。钛丝驱动技术目前已经在航空航天、洲际导弹......
  • Java三大特性:封装、继承、多态【详解】
    封装定义隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别便是封装。在开发中造一个类就是封装,有时也会说封装一个类。封装可以隐藏一些细节或者包含数据不能被随意修改。比如这是一个敏感的数据,我不能够让别人直接操纵到这个数据,因此我......