TCP为什么可靠之“重传机制”

TCP重传机制

TCP针对数据包丢失的情况,会通过重传机制解决,包括像超时重传、快速重传、选择确认SACK、D-SACK

超时重传

TCP会设置一个定时器,如果在发送数据之后的规定时间内,没有收到对方的ACK报文,就会触发重新发送数据。那么这个规定的时间应该设置为多少呢?这里有两个时间的概念

  • RTT(Round-Trip Time):往返时延,也就是从发送数据开始到接收应答报文的时间

  • RTO(Retransimission Timeout):超时重传时间,在数据发送之后开始,如果RTO时间内没有收到ACK报文,就会重新发送报文

超时重传时间如果设置的太小,会导致数据包还没有到达对方主机,或者是对方确认应答还没有到达本机时,就重新发送数据包,导致重复发送、网络负荷增大;如果设置的太大,会导致丢包后重新发送数据包的空闲时间太长,降低传输效率。

所以超时重传的时间应该略大于往返时延,这才能保证不会太大或太小。

由于网络是不断波动和变化的,所以RTT往返时延和RTO不会是一个固定的值。在Linux系统中,为了得到RTO,需要对RTT进行采样,然后加权计算出平滑RTT值,同时采样波动范围。根据RFC的标准以及大量的实验不断调试,最终得出了超时重传的这么一个策略:

  • 超时 间隔加倍:每当需要超时重传时,就将下一次的超时重传时间设置为原先的两倍。连续的两次超时,就说明网络环境差,不宜反复发送

超时重传是以时间作为重传的标准,需要等待超时才触发重传,所以它时间相对比较长,有没有更快的方式能够感知数据包丢失而触发重传呢?

快速重传

与超时重传不同,快速重传以数据作为标注,触发重传机制。

快速重传是指,当连续三次收到相同序号的ACK报文,就认为数据包丢失,需要重传,而不用等待超时再重传。

但快速重传面临着一个问题,是重传一个报文,还是包括该报文之后的所有报文?

  • 如果重传一个报文,在连续多个报文丢失的情况下,一次重传无法重传所有丢失的报文,需要触发下一次重传

  • 如果重传所有报文,可能导致重复发送已经被对方成功接收的数据,导致资源浪费

所以为了解决这个问题,有了之后的选择确认SACK

选择确认SACK

通过选择确认(Selective ACK),能够重传对方缺少的数据,而不重传已经成功被对方接收的数据。

要使用选择确认SACK,就需要在建立TCP连接时,在TCP报文头部的选项字段中加上”允许SACK“。

当接收方发生数据缺失时,就把确实报文的序号范围添加到TCP报文头部中,用来告知发送方哪些序号的报文需要重发。一个数据块有两个边界,指明一个边界就要用掉4个字节(因为边界指的就是序号,一个序号占4个字节),而TCP选项字段最长可达40字节。

D-SACK

Duplicate SACK,通过SACK字段,来告诉对方哪些数据被重复接收了。

导致数据的重复发送主要有两个场景,一个是没有收到ACK报文,另一个是网络延迟。

D-SACK的唯一作用就是能够让发送方知道,重传的原因,是因为自己发送的数据丢失了,还是对方的ACK报文丢失了,还是因为网络阻塞导致的数据延迟。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt开发流程】之容器类2:使用STL风格迭代器进行遍历

概述 对于每个容器类,都有两种stl风格的迭代器类型:一种提供只读访问,另一种提供读写访问。应该尽可能使用只读迭代器,因为它们比读写迭代器快。 STL迭代器的API以数组中的指针为模型。例如,操作符将迭代器推进到下一项&#xf…

vue2+datav可视化数据大屏(1)

开始 📓 最近打算出一个前端可视化数据大屏的系列专栏,这次将很全面的教大家设计可视化大屏,从开始到打包结束,其中,包括如何设计框架,如何封装axios,等等,本次使用的数据均为mock数…

关于AllowBeanDefinitionOverriding属性设置问题

📢📢📢📣📣📣 哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步🤝🤝 一位上进心十足的【Java ToB端大厂…

二叉树的OJ练习(二)

通过前序遍历数组构建二叉树 题目:通过前序遍历的数组(ABD##E#H##CF##G##)构建二叉树 TreeNode* TreeCreat(char* a,int* pi) {if(a[*pi] #){(*pi);return NULL; }TreeNode* root (TreeNode*)malloc(sizeof(TreeNode));if(root NULL){p…

【Unity动画】Avatar Mask

创建 Avatar Mask可以设置那一部分骨骼运动和不运动 然后放在状态机里面的层中来混合 【后续完善】

前端入门:HTML初级指南,网页的简单实现!

代码部分&#xff1a; <!DOCTYPE html> <!-- 上方为DOCTYPE声明&#xff0c;指定文档类型为HTML --> <html lang"en"> <!-- html标签为整个页面的根元素 --> <head> <!-- title标签用于定义文档标题 --> <title>初始HT…

快速测试 3节点的redis sentinel集群宕机2个节点以后是否仍能正常使用

有同事问我&#xff0c;三个redis sentinel节点&#xff0c;宕机两个节点以后&#xff0c;是否还能够正常的通过redis sentinel正常访问redis的数据。我想了想&#xff0c;理论上是可以的&#xff0c;但是我没试过&#xff0c;今天有时间就测试了一下。搭建环境和测试代码的过程…

Linux Component概述和高通component的使用

1 Linux为什么要引入Component框架&#xff1f; 为了让subsystem按照一定顺序初始化设备才提出来的。 subsystem中由很多设备模块&#xff0c;内核加载这些模块的时间不确定。子系统内有些模块是需要依赖其它模块先初始化才能进行自己初始化工作(例如v4l2 subdev和v4l2 video …

虚拟化之通用计时器

Arm架构包含通用定时器(Generic Timer),这是每个处理器中都有的一组标准化定时器。通用定时器包括一组比较器,这些比较器与一个共同的系统计数进行比较。当比较器的值等于或小于系统计数时,该比较器会生成中断。在下图中,我们可以看到系统中的通用定时器(橙色)以及其比…

HTML+CSS+JavaScript制作简单轮播图

一 运行效果 二 图片资源 三 代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>img{position:absolute;top:6%;left:20%;width:800px;height:240px;}.picture {back…

【FMCW毫米波雷达设计 】 — FMCW波形

原书&#xff1a;FMCW Radar Design 1 引言 本章研究驱动FMCW雷达的主要波形:线性调频(LFM)波形。我们研究信号的行为及其性质。随后&#xff0c;本章讨论了匹配滤波理论&#xff0c;并研究了压缩这种波形的技术&#xff0c;特别是所谓的拉伸处理&#xff0c;它赋予FMCW雷达极…

最长子序列问题(LCS)--动态规划解法

题目描述&#xff1a; 如果Z既是X的子序列&#xff0c;又是Y的子序列&#xff0c;则称Z为X和Y的公共子序列。 如果给定X、Y&#xff0c;求出最长Z及其长度。 示例&#xff1a; 输入 ABCPDSFJGODIHJOFDIUSHGD OSDIHGKODGHBLKSJBHKAGHI 输出 SDIHODSHG 9 分析&#xff1a…

课堂练习4.2:页式内存管理

4-3 课堂练习4.2:页式内存管理 创建一个进程(创建进程是在磁盘中),进程以字节为单位编号,然后再进程分为许多页(每页 4KB ),内存中有对应的页框(设定同页)。通过页表(记录页和页框的对应关系),将最需要的页调入内存,其他页留在磁盘中。根据 CPU 的需要动态的更新…

鸿蒙开发之封装优化

面向对象开发离不开封装&#xff0c;将重复的可以复用的代码封装起来&#xff0c;提高开发效率。 基于之前的List&#xff0c;对代码进行封装。 1、抽取component 将List的头部抽离出来作为一个新的component。可以创建一个新的ArkTS文件&#xff0c;写我们的头部代码 为了…

Springboot获取jar版本方法

Springboot获取jar版本方法 方案一: 通过jar的pom.properties文件获取 获取demo Properties properties new Properties(); try {properties.load(RakicAppInfo.class.getResourceAsStream("/META-INF/maven/com.rakic.framework/rakic-app-springboot-start/pom.pro…

Kubernetes里的DNS;API资源对象ingress;Kubernetes调度;节点选择器NodeSelector;节点亲和性NodeAffinity

Kubernetes里的DNS K8s集群内有一个DNS服务&#xff1a; kubectl get svc -n kube-system |grep dns测试&#xff1a; 在tang3上安装bind-utils,目的是安装dig命令 yum install -y bind-utils apt install dnsutils #ubuntu上 解析外网域名 dig 10.15.0.10 www.baidu.com…

JavaScript-节点操作

节点操作 DOM节点 DOM节点&#xff1a;DOM树里每一个内容都称之为节点 节点类型&#xff1a; 元素节点 所有的标签 比如body、divhtml时跟节点 属性节点 所有的属性&#xff0c;比如href 文本节点 所有的文本 其他 查找节点 节点的关系&#xff1a;针对的找亲戚返回的都是…

63. 不同路径 II

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到右下角…

查找算法——线性查找、二分查找

列表查找&#xff1a;从列表中查找指定元素。 列表查找的两种方法备注 顺序查找 (也叫线性查找) 两种方式&#xff1a; &#xff08;1&#xff09;自己写段代码。 &#xff08;2&#xff09;用列表内置函数index( ) 列表有序无序都可以。二分查找自己写段代码 列表必须有序&a…

动态规划_最小花费爬楼

//给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 // // 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 // // 请你计算并返回达到楼梯顶部的最低花费。 …