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

【TCP】核心机制:延时应答、捎带应答和面向字节流

文章目录

  • 延时应答
  • 捎带应答
  • 面向字节流
    • 粘包问题
      • 方案一:指定分隔符
      • 方案二:指定数据的长度
  • TCP 报头
    • 首部长度
    • 保留(6 位)
    • 选项
    • 序号
    • 确认序号

延时应答

尽可能降低可靠传输带来的性能影响
提升性能==>让滑动窗口变大

image.png|396

  • 如果我们立即返回 ACK,此时窗口大小就是 4KB
  • 其实在收到数据的时候,应用程序也在源源不断的消费接收缓冲区中的数据
    • 所以我们返回的时间可以晚一些,这样应用程序就有机会读取缓冲区中更多的数据
    • 假设让 ACK 不是立即返回,而是 100ms 之后再进行返回,这就意味着,此时在 100ms 之内,应用程序可能又消费掉 2KB 的数据了,此时返回的 ACK 携带的窗口大小就是 6KB
      延时返回的 ACK 窗口大小,大概率要比立即返回 ACK 的窗口大小更大,因为在这个时间里,会有一个消费数据的过程
  • 不是一定,只是有“大概率”,关键取决于程序是不是在不停地读取数据、延时时间内发送方是否会新发数据过来(发多了窗口还变得更小了)

捎带应答

在延时应答的基础上,引入的提升效率的机制,把返回的业务数据和 ACK 两者合二为一了

实际网络通信中,大部分情况都是“一问一答”的形式
image.png

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

比如说,你在床上口渴了,但是你不想起来,就等到要上厕所的时候再起来,顺带把水喝了

延时应答,捎带应答都是 TCP 提升性能的机制。TCP 之所以复杂,不仅仅在考虑可靠传输,还要在可靠传输的基础上尽可能提高效率

面向字节流

读写 100 个字节的数据

  1. 可以一次读写一个字节,分 100 次
  2. 一次读写 10 个字节,分 10 次
  3. 一次读写 50 个字节,分 2 次
  4. 一次读写 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 报头

image.png|449

首部长度

TCP 报头的长度

  • UDP 协议报头固定就是 8 个字节
  • 对于 TCP 来说,报头长度是可变的
    4 个比特位可表示的范围:
  • 0000~1111——>0x0~0xF——>0~15
  • 此处的长度单位是 4 字节,不是字节(所以范围是 0~60 字节)

保留(6 位)

虽然现在不用,但是先把这个东西申请下来,以备不时之需。用于考虑未来的可扩展性

  • 充分吸取了 UDP 的教训,UDP 的报文长度字段,是没法扩展的
  • 如果未来某一天,TCP 需要新增属性或者谋和属性的长度不够用,就可以把保留位拿出来,进行使用
  • TCP 的结构不需要发生太大的改变,这样的升级就会容易很多

关于“可扩展性”也是属于编程的时候需要考虑到的一点,毕竟写的代码不可能写一份就能持续地使用。对代码做出调整,做出修改,是非常普遍、常见的情况
但是,

选项

TCP 报头边长的主要原因。四个字节为一个单位

  • 可以有, 也可以没有
  • 可有一个,也可有多个
    通过“首部长度”确定报头有多长,如果是两个四个字节长度就是两个选项,三个四个字节长度就是三个选项,以此类推

序号

由于会出现“后发先至”的情况,所以需要通过编号,区分出数据的先后顺序
序号:表示的就是 TCP 数据报载荷中的第一个字节的序号,由于序号是连续递增,知道了第一个字节的序号,后续每个字节的序号也就知道了
image.png|565

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

确认序号

确认序号的设定方式,和后发先至中发短信的例子,略有差别

  • TCP 序号不是按照“一条两条”来编排的,而是按照“字节”来编排的
    image.png|357

TCP 的确认序号这里,填写的是 1001,接收方收到的数据的最后一个字节序号的下一个序号

  • 表示的含义是 <1001 的序号的数据都收到了(TCP 序号是连续增长的)
  • 对于应答报文来说,“确认序号”就会按照收到的数据的最后一个字节序号+1 的方式来填写
  • 并且六个标志位中,第二个标志位(ACK)会设为 1
    • 普通报文的 ACK0,应答报文的 ACK1
    • 如果是普通报文,序号是有效的,确认序号是无效的;如果是应答报文,序号和确认序号都是有效的
    • 应答报文的序号是另一套编号体系,和传输数据的序号是不一样的
    • 应答报文默认情况下是不携带数据的

相关文章:

【TCP】核心机制:延时应答、捎带应答和面向字节流

文章目录 延时应答捎带应答面向字节流粘包问题方案一&#xff1a;指定分隔符方案二&#xff1a;指定数据的长度 TCP 报头首部长度保留&#xff08;6 位&#xff09;选项序号确认序号 延时应答 尽可能降低可靠传输带来的性能影响 提升性能>让滑动窗口变大 如果我们立即返回 …...

题解:AT_abc352_e [ABC352E] Clique Connect

[题目通道]([ABC352E] Clique Connect - 洛谷) 鄙人今日写人生第一篇题解 希望管理大大通过 首先&#xff0c;我们先看题: 它说一共有n个点&#xff0c;m回操作。。。 每次操作 都有 一个Ki 和 Ci Ki代表有Ki个点,Ci代表每条边所赋的边权 一看就知道这是个最小生成树的板子…...

【代码随想录训练营第42期 Day32打卡 - 从零开始动态规划 - LeetCode 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

目录 一、做题心得 二、动规五步走 三、题目与题解 题目一&#xff1a;509. 斐波那契数 题目链接 题解1&#xff1a;记忆性递归 题解2&#xff1a;动态规划 题目二&#xff1a;70. 爬楼梯 题目链接 题解&#xff1a;动态规划 题目三&#xff1a;746. 使用最小花费爬楼…...

源码构建LAMP

目录 一、安装Apache 二、安装Mysql 三、安装PHP 四、安装论坛 一、安装Apache 1.cd 到opt目录下面&#xff0c;将压缩包拉进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 内核中&#xff0c;pinctrl子系统是一个专门用于管理和控制 SoC引脚复用和配置的子系统。SoC 通常具有大量的引脚&#xff08;pin&#xff09;&#xff0c;这些引脚可以被配置为不同的功能&#xff0c;比如 GPIO&#xff08;通用输入输出&…...

网络通信要素

网络介绍 定义&#xff1a;将具有独立功能的多台计算机通过通信线路和通信设备连接起来&#xff0c;在网络管理软件及网络通信协议下&#xff0c;实现资源共享和信息传递的虚拟平台。 学习网络的目的&#xff1a; 能够编写基于网络通信的软件或程序&#xff0c;通常来说就是网…...

day03_作业

一、简答题 继承的格式与好处 格式&#xff1a;class A extends B 好处&#xff1a;1.可以实现代码的复用&#xff0c;将共性的代码向上抽取&#xff0c;抽取到父类中。需要使用这些属性和行为的类&#xff0c;通过继承即可使用。2.当需要添加新的功能时&#xff0c;可以通过…...

pyinstaller程序打包,资源嵌入exe

参考&#xff1a;https://blog.csdn.net/qq_48979387/article/details/132359366 一、参数说明 -F 最终打包为一个可执行文件。-w 取消Windows显示窗口-add-data ‘dll;dll’&#xff0c;将当前目录dll下的文件打包到可执行文件的dll中&#xff0c;最终会在解压文件的dll文件…...

如何使用 OCR 和 GPT-4o mini 轻松提取收据信息

利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取 利用 OCR 和强大的 GPT-4o 迷你模型对收据进行信息提取 欢迎来到雲闪世界。&#xff0c;我将向您展示如何从收据中提取信息&#xff0c;并提供收据的简单图像。首先&#xff0c;我们将利用 OCR 从收据中提取信息。然后&a…...

go 事务

事务处理 首先启动事务时一定要做错误判断建议在启动事务之后马上写defer方法在defer方法内对err进行判断&#xff0c;如果全局中有err!nil就回滚全局中err都为nil则提交事务在提交事务之后我们可以定义一个钩子函数afterCommit&#xff0c;来统一处理事务提交后的逻辑。 示例…...

C,数据结构,多进程线程,网络编程面试题总结

目录 1.指针数组和数组指针 2.结构体字节对齐 3.Tcp和Udp的区别 4.同步通信和异步通信的区别 5.多线程理解 6.大小端验证 7.互斥锁相关问题 8.共享内存特点 9.c中的指针 10.Gcc编译 11.Socket的了解 12.Ip地址和子网掩码如何决定网卡所在的网段 13.数据结构中栈与…...

【Cesium学习】着色器详解【待进一步总结】

在Cesium中&#xff0c;drawCommand 和 CustomShader 是与渲染管线和自定义渲染效果相关的两个重要概念&#xff0c;但它们各自有不同的作用和应用场景。下面我将分别详解这两个概念。 drawCommand drawCommand 是 Cesium 渲染引擎内部使用的一个概念&#xff0c;它代表了单个…...

【3】静态路由(Static routing)

目录 一、有类路由和无类路由 二、路由的基本知识 三、配置 路由的组成&#xff1a; 四、特殊——默认路由 五、优点和缺点 六、实验 数据通信是双向的&#xff0c;路由器不同的接口属于不同的广播域和冲突域 一、有类路由和无类路由 有类路由&#xff1a;有ABC类别之…...

阿里声音项目Qwen2-Audio的部署安装,在服务器Ubuntu22.04系统——点动科技

阿里声音项目Qwen2-Audio的部署安装&#xff0c;在服务器Ubuntu22.04系统——点动科技 一、ubuntu22.04基本环境配置1.1 更换清华Ubuntu镜像源1.2 更新包列表&#xff1a;2. 安装英伟达显卡驱动2.1 使用wget在命令行下载驱动包2.2 更新软件列表和安装必要软件、依赖2.2 卸载原有…...

RAG(检索增强生成)

RAG (Retrieval-Augmented Generation) 是一种自然语言处理的模型架构&#xff0c;主要用于生成性任务&#xff0c;如文本生成、对话系统等。RAG 将检索和生成两个任务结合起来&#xff0c;以提高生成结果的质量和相关性。 RAG 模型的主要思想是通过检索阶段获取相关的上下文信…...

AcWing848有向图的拓扑排序

拓扑排序的流程&#xff1a; 插入&#xff08;a&#xff0c;b&#xff09;&#xff0c;表示a->b的关系&#xff0c;调用add(a,b),每次吧b的入度1&#xff0c;d[b]; 然后调用topsort&#xff0c;返回1表示存在拓扑序列&#xff0c;返回0表示不存在拓扑序列。判断是否存在拓扑…...

猫咪掉毛很严重,家中猫毛该如何清理?快来看资深铲屎官经验分享

想必铲屎官们都见识过换毛季的威力。拿我家举例&#xff0c;养了一只长毛&#xff0c;一只短毛&#xff0c;打扫完不用半天&#xff0c;家里就能重新出现不少猫毛。严重的时候&#xff0c;每天都要扫地机器人扫三次&#xff0c;拖一次。 最近两天外出&#xff0c;回来给它们梳…...

Midjourney进阶-反推与优化提示词(案例实操)

​ Midjourney中提示词是关键&#xff0c;掌握提示词的技巧直接决定了生成作品的质量。 当你看到一张不错的图片&#xff0c;想要让Midjourney生成类似的图片&#xff0c;却不知道如何描述画面撰写提示词&#xff0c;这时候Midjourney的/describe指令&#xff0c;正是帮助你推…...

大公报发表欧科云链署名文章:发行港元稳定币,建Web3.0新生态

欧科云链研究院资深研究员蒋照生近日与香港科技大学副校长兼香港Web3.0协会首席科学顾问汪扬、零壹智库创始人兼CEO柏亮&#xff0c;在大公报发布联合署名文章 ——《Web3.0洞察 / 发行港元稳定币&#xff0c;建Web3.0新生态》&#xff0c;引发市场广泛讨论。 文章就香港稳定币…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

spring boot使用HttpServletResponse实现sse后端流式输出消息

1.以前只是看过SSE的相关文章&#xff0c;没有具体实践&#xff0c;这次接入AI大模型使用到了流式输出&#xff0c;涉及到给前端流式返回&#xff0c;所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...

宠物车载安全座椅市场报告:解读行业趋势与投资前景

一、什么是宠物车载安全座椅&#xff1f; 宠物车载安全座椅是一种专为宠物设计的车内固定装置&#xff0c;旨在保障宠物在乘车过程中的安全性与舒适性。它通常由高强度材料制成&#xff0c;具备良好的缓冲性能&#xff0c;并可通过安全带或ISOFIX接口固定于车内。 近年来&…...

边缘计算设备全解析:边缘盒子在各大行业的落地应用场景

随着工业物联网、AI、5G的发展&#xff0c;数据量呈爆炸式增长。但你有没有想过&#xff0c;我们生成的数据&#xff0c;真的都要发回云端处理吗&#xff1f;其实不一定。特别是在一些对响应时间、网络带宽、数据隐私要求高的行业里&#xff0c;边缘计算开始“火”了起来&#…...

CMake系统学习笔记

CMake系统学习笔记 基础操作 最基本的案例 // code #include <iostream>int main() {std::cout << "hello world " << std::endl;return 0; }// CMakeLists.txt cmake_minimum_required(VERSION 3.0)# 定义当前工程名称 project(demo)add_execu…...

个人电脑部署本地大模型+UI

在这个AI飞速进步的时代&#xff0c;越来越多的大模型出现在市面上 本地大模型也越来越火爆&#xff01; 它完全免费&#xff0c;随时可以访问&#xff0c;数据仅存在本地&#xff0c;还可以自己微调&#xff0c;训练&#xff01; 今天我来教大家&#xff0c;如何在一台普通…...

【笔记】解决MSYS2安装后cargo-install-update.exe-System Error

#工作记录 cargo-install-update.exe-System Error The code execution cannot proceed because libgit2-1.9.dll wasnot found. Reinstalling the program may fix this problem. …...