【TCP】核心机制:延时应答、捎带应答和面向字节流
文章目录
- 延时应答
- 捎带应答
- 面向字节流
- 粘包问题
- 方案一:指定分隔符
- 方案二:指定数据的长度
- TCP 报头
- 首部长度
- 保留(6 位)
- 选项
- 序号
- 确认序号
延时应答
尽可能降低可靠传输带来的性能影响
提升性能==>让滑动窗口变大

- 如果我们立即返回
ACK,此时窗口大小就是4KB - 其实在收到数据的时候,应用程序也在源源不断的消费接收缓冲区中的数据
- 所以我们返回的时间可以晚一些,这样应用程序就有机会读取缓冲区中更多的数据
- 假设让
ACK不是立即返回,而是100ms之后再进行返回,这就意味着,此时在100ms之内,应用程序可能又消费掉2KB的数据了,此时返回的ACK携带的窗口大小就是6KB
延时返回的ACK窗口大小,大概率要比立即返回ACK的窗口大小更大,因为在这个时间里,会有一个消费数据的过程
- 不是一定,只是有“大概率”,关键取决于程序是不是在不停地读取数据、延时时间内发送方是否会新发数据过来(发多了窗口还变得更小了)
捎带应答
在延时应答的基础上,引入的提升效率的机制,把返回的业务数据和 ACK 两者合二为一了
实际网络通信中,大部分情况都是“一问一答”的形式

ACK是内核返回的,是收到请求之后,立即就返回ACK- 响应,则是应用程序返回的,代码中根据请求,计算得到响应,再把响应写回到客户端
正常情况下,ACK和响应是不同的时机,无法合并。但是,ACK涉及到“延时应答”, - 延时应答就会使
ACK的返回时间被往后拖,这样一延时,就可能赶上接下来发送响应数据的操作了 - 也是就可以在发送响应的时候,把刚才
ACK的信息也带上- 本身
ACK报文,不需要载荷,包头中,设置ACK这一位为1,设置窗口大小的值,设置确认序号 - 响应数据主要是设置载荷,和
ACK不冲突,可以共存

- 本身
- 在四次挥手中也说到过这样的情况,ACK 和 FIN 是不同的时机,不能合并在一起
- 但是,在延时应答之下,ACK 可能返回的时间更晚,此时,就可能可以和 FIN 合并,使四次挥手变成三次挥手
比如说,你在床上口渴了,但是你不想起来,就等到要上厕所的时候再起来,顺带把水喝了
延时应答,捎带应答都是 TCP 提升性能的机制。TCP 之所以复杂,不仅仅在考虑可靠传输,还要在可靠传输的基础上尽可能提高效率
面向字节流
读写 100 个字节的数据
- 可以一次读写一个字节,分 100 次
- 一次读写 10 个字节,分 10 次
- 一次读写 50 个字节,分 2 次
- 一次读写 100 个字节,一次搞定
- …
粘包问题
通过面向字节流的方式传输数据,都是会涉及到“粘包问题”
-
粘的是 TCP 携带的载荷(应用层数据包)
-
aaa、bbb、ccc 分别是三个不同的应用层数据包
-
接收方那边就有一个接收缓冲区,三个数据就进去了
-
应用程序需要读取接收缓冲区中的数据,由于 TCP 是面向字节流的,所以怎么读都可以
- 可以读成:a,aa,b,bb,ccc
- 也可以:aaa,b,b,bc,cc
- 存在很多种读法
-
但只有一是正确的读法,才是完整的“应用层数据包”
应用层在 TCP 的接收缓冲区中连成一片,就称为“粘包问题”
要想解决粘包问题,关键就是要明确“包之间的边界”
方案一:指定分隔符
前面在写
TCP Echo Server的时候,我们约定:请求和响应都以\n结尾。
- 发送请求响应的时候,专门使用
println进行写数据- 接受请求响应的时候,专门使用
scanner.next按照\n进行解析
需要确认数据内容的正文中,不能包含分隔符。如果传输的数据,是纯文本数据的话,此时使用 \n 或者 ; 之类的可能都不合适,但是可以使用 ASCII 码表中的一些不常见的字符
方案二:指定数据的长度
比如,约定在每个应用层数据包开头的几个字节,表示数据包的长度
- 如果是传输二进制数据,这个方案就很有用
如果希望在文件中存储结构化数据,也是存在这样的问题的。所以存文件,也经常会使用 XML/JSON 这样的格式来存储(也就是解决粘包问题)
UDP 这种面向数据报的传输方式,不涉及到上述问题,因为 send/receive 得到的就是一个完整的 DatagramPacket,这里携带的二进制的字节数组,就是一个完整的应用层数据包
TCP 报头

首部长度
TCP 报头的长度
UDP协议报头固定就是8个字节- 对于
TCP来说,报头长度是可变的
4 个比特位可表示的范围: 0000~1111——>0x0~0xF——>0~15- 此处的长度单位是 4 字节,不是字节(所以范围是
0~60字节)
保留(6 位)
虽然现在不用,但是先把这个东西申请下来,以备不时之需。用于考虑未来的可扩展性
- 充分吸取了
UDP的教训,UDP的报文长度字段,是没法扩展的 - 如果未来某一天,
TCP需要新增属性或者谋和属性的长度不够用,就可以把保留位拿出来,进行使用 TCP的结构不需要发生太大的改变,这样的升级就会容易很多
关于“可扩展性”也是属于编程的时候需要考虑到的一点,毕竟写的代码不可能写一份就能持续地使用。对代码做出调整,做出修改,是非常普遍、常见的情况
但是,
选项
TCP 报头边长的主要原因。四个字节为一个单位
- 可以有, 也可以没有
- 可有一个,也可有多个
通过“首部长度”确定报头有多长,如果是两个四个字节长度就是两个选项,三个四个字节长度就是三个选项,以此类推
序号
由于会出现“后发先至”的情况,所以需要通过编号,区分出数据的先后顺序
序号:表示的就是 TCP 数据报载荷中的第一个字节的序号,由于序号是连续递增,知道了第一个字节的序号,后续每个字节的序号也就知道了

- 32 位/四字节,表示的范围是
0~42亿9千万(0~4G) - 因为
TCP是面向字节流的,所以一个TCP数据报和下一个TCP数据报携带的数据,是可以直接进行拼装的 - 比如要传输一个特别大的数据,传输过程中,本身就会通过多个
TCP数据报来进行携带,这些TCP数据报彼此之间携带的载荷都是可以在接受方自动拼起来的- 这样就不像
UDP存在传输的上限,使用UDP传输大数据,就需要考虑调用这一次send操作,参数是否超过了64KB,超过了就不行 - 使用
TCP的话就没关系,可以调用一次write,也可以调用多次write。无论怎么进行write,在网络传输和对端接收的角度来看是没有任何差别的 - 如果多次
write,传输的总数据量超过上述的4G也没关系,这里的数据序号是可以再从 0 开始重新设置的
- 这样就不像
确认序号
确认序号的设定方式,和后发先至中发短信的例子,略有差别
- TCP 序号不是按照“一条两条”来编排的,而是按照“字节”来编排的

TCP 的确认序号这里,填写的是 1001,接收方收到的数据的最后一个字节序号的下一个序号
- 表示的含义是
<1001的序号的数据都收到了(TCP序号是连续增长的) - 对于应答报文来说,“确认序号”就会按照收到的数据的最后一个字节序号
+1的方式来填写 - 并且六个标志位中,第二个标志位(
ACK)会设为1- 普通报文的
ACK为0,应答报文的ACK为1 - 如果是普通报文,序号是有效的,确认序号是无效的;如果是应答报文,序号和确认序号都是有效的
- 应答报文的序号是另一套编号体系,和传输数据的序号是不一样的
- 应答报文默认情况下是不携带数据的
- 普通报文的
相关文章:
【TCP】核心机制:延时应答、捎带应答和面向字节流
文章目录 延时应答捎带应答面向字节流粘包问题方案一:指定分隔符方案二:指定数据的长度 TCP 报头首部长度保留(6 位)选项序号确认序号 延时应答 尽可能降低可靠传输带来的性能影响 提升性能>让滑动窗口变大 如果我们立即返回 …...
题解:AT_abc352_e [ABC352E] Clique Connect
[题目通道]([ABC352E] Clique Connect - 洛谷) 鄙人今日写人生第一篇题解 希望管理大大通过 首先,我们先看题: 它说一共有n个点,m回操作。。。 每次操作 都有 一个Ki 和 Ci Ki代表有Ki个点,Ci代表每条边所赋的边权 一看就知道这是个最小生成树的板子…...
【代码随想录训练营第42期 Day32打卡 - 从零开始动态规划 - LeetCode 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯
目录 一、做题心得 二、动规五步走 三、题目与题解 题目一:509. 斐波那契数 题目链接 题解1:记忆性递归 题解2:动态规划 题目二:70. 爬楼梯 题目链接 题解:动态规划 题目三:746. 使用最小花费爬楼…...
源码构建LAMP
目录 一、安装Apache 二、安装Mysql 三、安装PHP 四、安装论坛 一、安装Apache 1.cd 到opt目录下面,将压缩包拉进Xhell 2.解压缩apr和httpd压缩包 tar xf apr-1.6.2.tar.gz tar xf apr-util-1.6.0.tar.gz tar xf httpd-2.4.29.tar.bz2 3.将apr-1.6.2 移动到ht…...
Java:封装树结构
实体类 public class DictTreeselectVO {private String value;private String label;/*** 节点*/private String parentId;private List<DictTreeselectVO> children new ArrayList<DictTreeselectVO>();public String getValue() {return value;}public void s…...
linux内核 pintrl子系统
1、什么是pinctrl子系统 在 Linux 内核中,pinctrl子系统是一个专门用于管理和控制 SoC引脚复用和配置的子系统。SoC 通常具有大量的引脚(pin),这些引脚可以被配置为不同的功能,比如 GPIO(通用输入输出&…...
网络通信要素
网络介绍 定义:将具有独立功能的多台计算机通过通信线路和通信设备连接起来,在网络管理软件及网络通信协议下,实现资源共享和信息传递的虚拟平台。 学习网络的目的: 能够编写基于网络通信的软件或程序,通常来说就是网…...
day03_作业
一、简答题 继承的格式与好处 格式:class A extends B 好处:1.可以实现代码的复用,将共性的代码向上抽取,抽取到父类中。需要使用这些属性和行为的类,通过继承即可使用。2.当需要添加新的功能时,可以通过…...
pyinstaller程序打包,资源嵌入exe
参考:https://blog.csdn.net/qq_48979387/article/details/132359366 一、参数说明 -F 最终打包为一个可执行文件。-w 取消Windows显示窗口-add-data ‘dll;dll’,将当前目录dll下的文件打包到可执行文件的dll中,最终会在解压文件的dll文件…...
如何使用 OCR 和 GPT-4o mini 轻松提取收据信息
利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取 利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取 欢迎来到雲闪世界。,我将向您展示如何从收据中提取信息,并提供收据的简单图像。首先,我们将利用 OCR 从收据中提取信息。然后&a…...
go 事务
事务处理 首先启动事务时一定要做错误判断建议在启动事务之后马上写defer方法在defer方法内对err进行判断,如果全局中有err!nil就回滚全局中err都为nil则提交事务在提交事务之后我们可以定义一个钩子函数afterCommit,来统一处理事务提交后的逻辑。 示例…...
C,数据结构,多进程线程,网络编程面试题总结
目录 1.指针数组和数组指针 2.结构体字节对齐 3.Tcp和Udp的区别 4.同步通信和异步通信的区别 5.多线程理解 6.大小端验证 7.互斥锁相关问题 8.共享内存特点 9.c中的指针 10.Gcc编译 11.Socket的了解 12.Ip地址和子网掩码如何决定网卡所在的网段 13.数据结构中栈与…...
【Cesium学习】着色器详解【待进一步总结】
在Cesium中,drawCommand 和 CustomShader 是与渲染管线和自定义渲染效果相关的两个重要概念,但它们各自有不同的作用和应用场景。下面我将分别详解这两个概念。 drawCommand drawCommand 是 Cesium 渲染引擎内部使用的一个概念,它代表了单个…...
【3】静态路由(Static routing)
目录 一、有类路由和无类路由 二、路由的基本知识 三、配置 路由的组成: 四、特殊——默认路由 五、优点和缺点 六、实验 数据通信是双向的,路由器不同的接口属于不同的广播域和冲突域 一、有类路由和无类路由 有类路由:有ABC类别之…...
阿里声音项目Qwen2-Audio的部署安装,在服务器Ubuntu22.04系统——点动科技
阿里声音项目Qwen2-Audio的部署安装,在服务器Ubuntu22.04系统——点动科技 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表:2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有…...
RAG(检索增强生成)
RAG (Retrieval-Augmented Generation) 是一种自然语言处理的模型架构,主要用于生成性任务,如文本生成、对话系统等。RAG 将检索和生成两个任务结合起来,以提高生成结果的质量和相关性。 RAG 模型的主要思想是通过检索阶段获取相关的上下文信…...
AcWing848有向图的拓扑排序
拓扑排序的流程: 插入(a,b),表示a->b的关系,调用add(a,b),每次吧b的入度1,d[b]; 然后调用topsort,返回1表示存在拓扑序列,返回0表示不存在拓扑序列。判断是否存在拓扑…...
猫咪掉毛很严重,家中猫毛该如何清理?快来看资深铲屎官经验分享
想必铲屎官们都见识过换毛季的威力。拿我家举例,养了一只长毛,一只短毛,打扫完不用半天,家里就能重新出现不少猫毛。严重的时候,每天都要扫地机器人扫三次,拖一次。 最近两天外出,回来给它们梳…...
Midjourney进阶-反推与优化提示词(案例实操)
Midjourney中提示词是关键,掌握提示词的技巧直接决定了生成作品的质量。 当你看到一张不错的图片,想要让Midjourney生成类似的图片,却不知道如何描述画面撰写提示词,这时候Midjourney的/describe指令,正是帮助你推…...
大公报发表欧科云链署名文章:发行港元稳定币,建Web3.0新生态
欧科云链研究院资深研究员蒋照生近日与香港科技大学副校长兼香港Web3.0协会首席科学顾问汪扬、零壹智库创始人兼CEO柏亮,在大公报发布联合署名文章 ——《Web3.0洞察 / 发行港元稳定币,建Web3.0新生态》,引发市场广泛讨论。 文章就香港稳定币…...
微软DebugMCP:可视化调试MCP协议,解决AI与工具通信黑盒问题
1. 项目概述:当你的AI助手开始“自言自语”,你需要一个调试器 最近在折腾AI应用开发的朋友,估计没少跟各种“智能体”打交道。无论是基于OpenAI的GPTs,还是那些能联网、能调用工具的自定义助手,它们背后的核心通信协议…...
编程统计公司内部资料查阅使用数据,优化资料分类存储方式。提升职场员工工作查阅办事效率。
构建一个公司内部资料查阅使用统计与资料分类存储优化的商务智能示例项目,去营销化、中立化,仅用于学习与工程实践参考。一、实际应用场景描述在中大型企业中,内部资料(制度、流程文档、技术手册、项目档案)数量庞大&a…...
深度解析Scarab:空洞骑士模组管理器的专业实现与架构设计
深度解析Scarab:空洞骑士模组管理器的专业实现与架构设计 【免费下载链接】Scarab An installer for Hollow Knight mods written with Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 空洞骑士模组管理器Scarab为玩家提供了高效、专业的模组…...
终极FGO自动化助手:告别枯燥刷本,每天节省3小时游戏时间
终极FGO自动化助手:告别枯燥刷本,每天节省3小时游戏时间 【免费下载链接】FGA Auto-battle app for F/GO Android 项目地址: https://gitcode.com/gh_mirrors/fg/FGA Fate/Grand Automata(简称FGA)是一款专为Fate/Grand Or…...
Cursor IDE事件日志分析工具:Python实现开发者行为可视化与效率洞察
1. 项目概述:一个为开发者“把脉”的智能分析工具如果你是一名开发者,尤其是深度使用Cursor这类AI编程助手的开发者,你肯定有过这样的体验:面对一个复杂的项目,你向AI助手提了无数个问题,生成了大量代码片段…...
AI驱动代码审查:Cursor与Git工作流融合实践
1. 项目概述:当AI代码助手遇上代码审查最近在GitHub上看到一个挺有意思的项目,叫guinacio/cursor-review。光看名字,你可能会觉得这又是一个普通的代码审查工具,但点进去仔细研究,你会发现它的核心思路非常巧妙&#x…...
基于Stable Diffusion与LoRA技术打造个人AI头像:从原理到实战
1. 项目概述:当AI开始“自拍”——SelfyAI的定位与核心价值最近在AI图像生成领域,一个名为SelfyAI的项目引起了我的注意。它不是一个简单的文生图工具,而是瞄准了一个非常具体且高频的需求:生成高质量、风格一致的个人AI头像。简单…...
Carapace:统一跨Shell命令行补全的Go语言引擎
1. 项目概述:一个为Shell而生的全能补全引擎 如果你和我一样,每天有超过一半的工作时间是在终端里度过的,那你一定对命令行补全这件事又爱又恨。爱的是,一个恰到好处的补全能让你行云流水,效率倍增;恨的是…...
Linux系统调用观察与strace实战
Linux系统调用观察与strace实战很多 Linux 问题只靠日志和进程状态很难看清,尤其是在进程存在但无响应、命令卡住不动、文件访问异常或网络连接莫名失败时。此时,观察进程正在进行哪些系统调用,往往能快速揭示它卡在什么地方。中级阶段必须掌…...
【独家首发】ElevenLabs马拉雅拉姆文支持状态实测报告(含ISO 639-2代码验证、音素对齐误差率<0.8%)
更多请点击: https://intelliparadigm.com 第一章:ElevenLabs马拉雅拉姆文支持的现状与战略意义 ElevenLabs 作为全球领先的语音合成平台,自2023年11月起正式将马拉雅拉姆语(Malayalam,ISO 639-1: ml)纳入…...
