TCP的重传机制
TCP 是一个可靠的传输协议,解决了IP层的丢包、乱序、重复等问题。这其中,TCP的重传机制起到重要的作用。
序列号和确认号
之前我们在讲解TCP三次握手时,提到过TCP包头结构,其中有序列号和确认号,
而TCP 实现可靠传输的方式之一,就是是通过序列号和确认应答。
-
序列号(Sequence Number):
- TCP是基于数据流的,序列号用于标识数据流中的字节位置,它表示数据包中的第一个字节在整个数据流中的位置。
- 接收方在接收到数据包后,会根据序列号对数据包进行排序和重组,确保数据的顺序正确。
-
确认号(Acknowledgement Number):
-
确认号用于确认接收方已经成功接收了数据,并且期望下一个接收到的数据包的序列号是多少。
-
在TCP通信中,接收方会向发送方发送一个确认数据包,其中包含了确认号,表示接收到的数据包中的最后一个字节的下一个字节的序列号。

-
我们可以用wireshark抓包来看一下TCP的序列号和确认号:

通过上图我们可以看到:
- 进行三次握手时,客户端的初始序列号是2924706275,服务端的初始序列号是1859008164。
- 发送第一个包时,序列号是2924706276,是初始序列号+1,表示当前数据是第一个字节,数据长度8字节。
- 服务端回复ACK时,确认号是2924706284,是客户端的初始序列号+9,表示已经接收到前8个字节,现在期待第9个字节。
- 客户端继续发第二个包,序列号2924706284,表示当前数据是第9个字节。
- 服务端回复ACK时,确认号是2924706292,是客户端的初始序列号+17,表示已经接收到前16个字节,现在期待第17个字节。
在wireshark中,可以显示相对的序列号,可以更直观地看到序列号的变化:

这里我们可以看到,服务端发的包,序列号一直是1,因为当前服务端只是接收数据,并没有发送数据,所以服务端的序列号一直是1,而客户端的确认号也一直是1,表示期待服务端发送第一个字节过来。
重传机制
正常情况下,当发送端的数据到达接收主机时,接收端主机会返回一个确认应答消息,表示已收到消息。
但在复杂的网络下,并不一定能顺利的进行数据传输,万一数据在传输过程中丢失了呢?针对数据包丢失的情况,TCP会用重传机制解决。
超时重传
重传机制的其中一个方式,就是在发送数据时,设定一个定时器,当超过指定的时间后,如果还没有收到对方的ACK确认应答报文,就会重发该数据,也就是我们常说的超时重传。

那么这个指定的时间,应该是多久比较合适呢?
这里先介绍两个概念:RTT和RTO
RTT(Round-Trip Time) 往返时延,指的是数据发送时刻到接收到确认的时刻的差值,也就是包的往返时间RTO(Retransmission Timeout),就是超时重传时间。
通常RTO应该略大于RTT:
- 如果
RTO太短,有可能数据没有丢失就重发,增加网络拥塞。 - 如果
RTO太长,重发就慢,性能差。
由于网络的不稳定,RTT是经常变化的,导致RTO也会是一个动态变化的值。
如果超时重发的数据,再次超时的话,下一次重传的时间间隔则会加倍。
超时重传存在的问题是,超时周期可能相对较长。那是不是可以有更快的方式呢?
TCP用快速重传机制来解决超时重发的时间等待。
快速重传
发送方发包的时候,并不总是等待ACK的响应再发送下一个包,而是会在窗口大小内,连续发多个包:

如果其中一个包丢失了,而后续的包到达时,接收方会发丢失的包的ACK给发送方。当发送方连接收到三个相同的ACK时,就知道这个包丢失了,于是不用等重传定时,直接就可以重新发送了:

通过wireshark抓包,在过滤器中输入tcp.analysis.fast_retransmission,我们可以观察到快速重传的现象:


SACK
快速重传机制解决了超时时间的问题,但是它面临着另外一个问题:那就是重传的时候,是重传一个包,还是重传所有的包?像上面的例子,客户端发出19个包,当触发快速重传的时候,客户端只知道第2个包丢失了,那其他包是否丢失,客户端并不清楚,这时候有两种选择:
- 重发2~19所有的包,显然会造成数据的浪费,因为后面17个包都是已经收到的。
- 只重发第2个包。但如果第3个包也丢失的话,那么又得等到三次ACK才能重发第3个包,效率较低。
这时候,SACK(Selective Acknowledgment),选择性确认,就可以起作用了。
这种方式需要在TCP头部选项字段里加一个SACK的选项,它可以将已收到的数据的信息发送给发送方 ,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据了 。

在这个例子中,SACK表示15870601~15873581之间的数据是已经收到的,所以客户端只需要重发15869201~15870600之间的数据就行了。
由于TCP头部大小的限制,在选项中最多能支持四组SACK的数据
相关文章:
TCP的重传机制
TCP 是一个可靠的传输协议,解决了IP层的丢包、乱序、重复等问题。这其中,TCP的重传机制起到重要的作用。 序列号和确认号 之前我们在讲解TCP三次握手时,提到过TCP包头结构,其中有序列号和确认号, 而TCP 实现可靠传输…...
pg 数据库,获取时间字段值的具体小时,赋值给其他字段
目录 1 问题2 实现 1 问题 pg 数据库,有一个表,其中有2个字段 一个是时间字段obstime ,一个是时次ltime字段,int 类型,现在这个表里面是obstime 里面有数据,ltime字段 没有数据,现在就是批量获…...
做视频号小店什么类目最容易爆单?其实,弄懂这三点就会选品了
大家好,我是电商花花。 我们做视频号小店做什么类目最容易爆单? 其实任何类目都有属于自己的受众人群和客户,都非常容易爆单,我们想要爆单,就要选对类目,选对产品。 视频号上所有的类目基本上可以分为标…...
Nginx作为下载站点
grep -Ev ^$|# /usr/local/nginx/conf/nginx.conf > /opt/nginx.txt cat /opt/nginx.txt > /usr/local/nginx/conf/nginx.conf用上面的指令提取最小化的配置文件 vim /usr/local/nginx/conf/nginx.conf [rootlocalhost ~]# cat /usr/local/nginx/conf/nginx.conf worker…...
vue3简单快速实现主题切换功能
⛰️个人主页: 蒾酒 🔥系列专栏:《vue3实战》 目录 内容概要 实现步骤 1.定义不同主题的css样式变量 2.入口main.ts中引入这个样式文件 3.主题样式css变量引用 4.设置默认主题样式 5.实现点击按钮主题切换 总结 最近发现了一个巨牛的人工智…...
国联易安:网络反不正当竞争,要防患于未然
据市场监管总局官网消息,为预防和制止网络不正当竞争,维护公平竞争的市场秩序,鼓励创新,保护经营者和消费者的合法权益,促进数字经济规范健康持续发展,市场监管总局近日发布《网络反不正当竞争暂行规定》&a…...
Linux 网络配置 01
基本命令 1、查看网络接口信息ifconfig ifconfig:当前设备正在工作的网卡,启动的设备 ifconfig -a :所网络设备 ifconfig信息解析: ens33: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.10.10 n…...
快速入门C++正则表达式
正则表达式(Regular Expression,简称 Regex)是一种强大的文本处理工具,广泛用于字符串的搜索、替换、分析等操作。它基于一种表达式语言,使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。正则表达式不仅在…...
java —— 缓冲字符输入流/缓冲字符输出流
缓冲字符输入流/缓冲字符输出流是对字符输入流/字符输出流的加强,在使用中仍旧要借助于字符输入流/字符输出流才能完成实现。与字符输入流/字符输出流按照字符为单位进行输入/输出不同的是,缓冲字符输入流/缓冲字符输出流能够以行为单位进行读取和写入。…...
blender从视频中动作捕捉,绑定到人物模型
总共分为3个步骤: 1、从视频中捕捉动作模型 小K动画网-AIGC视频动捕平台 地址:https://xk.yunbovtb.com/ 需要注册 生成的FBX文件,不能直接导入到blender中, 方法有2种: 第一种:需要转换一下&#x…...
掘金滑块验证码安全升级,继续破解
去年发过一篇文章,《使用前端技术破解掘金滑块验证码》,我很佩服掘金官方的气度,不但允许我发布这篇文章,还同步发到了官方公众号。最近发现掘金的滑块验证码升级了,也许是我那篇文章起到了一些作用,逼迫官…...
数据结构练习题——Java实现
20240531-时间复杂度 1、消失的数字 方法一:位运算 两个数字一样的数组,其中一个数组中少了一个数字,定义一个变量分别异或两个数组,结果即为缺少的数字 class Solution {public int missingNumber(int[] nums) {int xor 0;int…...
行为设计模式之状态模式
文章目录 概述定义结构图 2.代码示例小结 概述 定义 状态模式(state pattern)的定义: 允许一个对象在其内部状态改变时改变它的行为。 对象看起来似乎修改了它的类。 状态模式就是用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题.。状态模式将一个对象的状态…...
找回以前的视频:技术与实践3个指南
你们有没有发现现在视频已经成为我们生活中不可或缺的一部分了?不管是在工作场合做演示、在学习时看教学视频,还是在休闲娱乐时追剧看电影,视频都扮演着超级重要的角色。 然而误删或手机故障的发生很可能将以前的视频清除。本文将深入探讨手…...
GCN 代码解析(一) for pytorch
Graph Convolutional Networks 代码详解 前言一、数据集介绍二、文件整体架构三、GCN代码详解3.1 utils 模块3.2 layers 模块3.3 models 模块3.4 模型的训练代码 总结 前言 在前文中,已经对图卷积神经网络(Graph Convolutional Neural Networks, GCN&am…...
2024年云计算、信号处理与网络技术国际学术会议(ICCCSPNT 2024)
2024年云计算、信号处理与网络技术国际学术会议(ICCCSPNT 2024) 2024 International Academic Conference on Cloud Computing, Signal Processing, and Network Technology(ICCCSPNT 2024) 会议简介: 2024年云计算、…...
希尔排序法
希尔排序为插入排序的优化,即将数组分组,将每一组进行插入排序,每一组排成有序后,最后整体就变有序了。 上面gap2,即5,14,18,27,68为一组;13,20&a…...
thinkphp6.0版本下子查询sql处理
目录 一:背景 二:查询实例 三:总结 一:背景 我们在实际业务的开发过程中,经常会碰到这样的场景,查询某些部门的客户信息,查询下过订单的客户信息。这里查询客户信息实际上就用到了子查询&…...
flowable工作流 完成任务代码 及扩展节点审核人(实现多级部门主管 审核等)详解【JAVA+springboot】
低代码项目 使用flowable 工作流 完成任务代码 详解 可以看到 complete()方法 传递了流程变量参数var 前端传递此参数就可以实现 流程中 审批 更新流程变量参数var 也可以进行更多扩展 实现流程中更新表单内容功能 启动流程实例代码 实现对于流程自定义 动态节点审核人 功…...
【电源专题】一体成型电感为什么需要注意耐压问题
对于电感,我们在电路上使用的很多,如升压、降压、滤波等电路中基本上使用到了电感。电感的种类有很多,电感从不同的角度会有不同的分类。如可以根据否屏蔽、工艺类型、磁性材料类型等可分为多类,这在文章:【分立元件】电感器(inductor)——简介中有做了一些简单的介绍。…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
