Netty笔记10:LengthFieldBasedFrameDecoder很简单,请看
Netty笔记1:线程模型
Netty笔记2:零拷贝
Netty笔记3:NIO编程
Netty笔记4:Epoll
Netty笔记5:Netty开发实例
Netty笔记6:Netty组件
Netty笔记7:ChannelPromise通知处理
Netty笔记8:ByteBuf使用介绍
Netty笔记9:粘包半包
Netty笔记10:LengthFieldBasedFrameDecoder
Netty笔记11:编解码器
Netty笔记12:模拟Web服务器
Netty笔记13:序列化
文章目录
- 前言
- 什么是`LengthFieldBasedFrameDecoder`
- 理论
- 实践验证
- 粘包
- 半包
- 补充
前言
本部只是LengthFieldBasedFrameDecoder的理论总结,和理论验证。
什么是LengthFieldBasedFrameDecoder
LengthFieldBasedFrameDecoder处理基于长度字段的协议。它能够根据数据包中的长度字段来解析数据流,并将数据流分割成独立的帧;
因其能对数据包边界的识别,而应用于粘包和半包的处理;
理论
应用层协议都是基于TCP/IP进行开发的,传输数据时就会有协议特征,就是数据头,它不作为我们真正的有效数据;
那么在解码时,需要考虑,数据包长度,数据头长度,和数据体长度;
public LengthFieldBasedFrameDecoder(// 允许的最大数据长度(以字节为单位),就是你的一个数据最大多大,超过报异常int maxFrameLength,// 长度字段的开始索引下标int lengthFieldOffset, // 长度字段占用的字节数int lengthFieldLength,// 长度字段之后,开始读取的索引下标偏移量int lengthAdjustment, // 接收到的发送数据包,丢弃多少位int initialBytesToStrip) {
lengthFieldOffset、lengthFieldLength:这两个字段很好理解,就是解码器,要确定读取多少字节长度的数据,就必须先读取我们指定的长度字段,那么这两个字段就可以确定从哪一个索引下标开始,读取多少字节,以此来获取数据长度(底层读取方式:ByteBuf.getUnsignedInt(lengthFieldOffset));
lengthAdjustment:就是待读取数据的开始索引下标与长度字段结束索引的差值(带读取数据的开始索引 - 长度字段结束索引),或者是以长度字段结束索引为坐标0点,待读取数据的开始索引到0点的距离(左负右正);
那么,怎么判断待读取的开始位置?
从数据结构右边的尾部,向左移动长度字段值的位置就是开始索引位置,如长度字段(length)值是33,那么,从右边尾部向左移动33个索引位置就是开始位置,也或是看长度字段包含了哪些部分(长度字段包发的部分应是连续的数据块);
假设协议如下:
| header | length | header | 数据体1 4 8 x长度如上:4,4,8,x(未知)
画出坐标如下:

取值规则如下:
length值:数据体长度

取值:
lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=8 -> 长度字段与待读取数据的开始索引差值
length值:包含8字节的header,数据体

lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=0 -> 长度字段与待读取数据的开始索引差值
length值:包含本身长度,以及8字节的header,数据体

lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=-4 -> 长度字段与待读取数据的开始索引差值
length值:包含1字节的header,本身长度,以及8字节的header

lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=-5 -> 长度字段与待读取数据的开始索引差值
感觉画图不够清晰,下面是文字版的:
| header | length | header | 数据体1 4 8 x长度如上:4,4,8,x(未知)length值:数据体长度
| header | length | header | 数据体1 4 8 x^ ^| |0 从这开始读
则:
lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=8 -> 长度字段与待读取数据的开始索引差值length值:包含8字节的header,数据体| header | length | header | 数据体1 4 8 x^ | 0 从这开始读lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=0 -> 长度字段与待读取数据的开始索引差值length值:包含本身长度,以及8字节的header,数据体| header | length | header | 数据体1 4 8 x^ ^ | | 从这开始读 0 lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=-4 -> 长度字段与待读取数据的开始索引差值length值:包含1字节的header,本身长度,以及8字节的header| header | length | header | 数据体1 4 8 x
^ ^
| |
从这开始读 0 lengthFieldOffset=4 -> 长度字段开始索引下标
lengthFieldLength=4 -> 长度字段长度
lengthAdjustment=-5 -> 长度字段与待读取数据的开始索引差值
实践验证
LengthFieldBasedFrameDecoder要做数据流解析验证用的,所以放在第一个,待它根据我们指定的规则解析数据流后,将独立的帧(数据头、长度字段、数据体等)作为一个完整的数据包传给下一个handler;
粘包
步骤:
-
创建一个
MessageToByteEncoder,消息写入时,将消息组装各部分帧:长度字段,数据头,和数据体; -
客户端发送多次数据,或者一次将多个消息数据合并为一个
ByteBuf发送(模拟粘包); -
服务端第一个添加
LengthFieldBasedFrameDecoder,第二个添加我们自定义的handler用来获取数据和判断读取次数; -
出站
handler,连续写入两个数据包,但只发送一次public class MBHandler extends MessageToByteEncoder<UserInfo> {private static final long serializable = 123456789;private static final int type = 1;@Overrideprotected void encode(ChannelHandlerContext ctx,
相关文章:
Netty笔记10:LengthFieldBasedFrameDecoder很简单,请看
Netty笔记1:线程模型 Netty笔记2:零拷贝 Netty笔记3:NIO编程 Netty笔记4:Epoll Netty笔记5:Netty开发实例 Netty笔记6:Netty组件 Netty笔记7:ChannelPromise通知处理 Netty笔记8:ByteBuf使用介绍 Netty笔记9:粘包半包 Netty笔记10:LengthFieldBasedFrameDec…...
linux 安装Mysql无法远程访问问题的排查
宝塔面板安装了mysql5.6后 只能本地访问 firewall 在使用宝塔面板(BT Panel)安装 MySQL 5.6 后,如果你发现 MySQL 只能本地访问,而不能从其他机器或服务访问,这通常是由于防火墙设置或 MySQL 配置的问题。以下是一些步…...
DeepSeek搭配Excel,制作自定义按钮,实现办公自动化!
今天跟大家分享下我们如何将DeepSeek生成的VBA代码,做成按钮,将其永久保存在我们的Excel表格中,下次遇到类似的问题,直接在Excel中点击按钮,就能10秒搞定,操作也非常的简单. 一、代码准备 代码可以直接询问…...
英文生物信息学技术社区Top10推荐:基本情况、评介和网页链接
英文生物信息学技术社区Top10推荐:基本情况、评介和网页链接 李升伟 一、思考与分析 生物信息学涉及生物数据分析和计算工具,所以相关的社区可能包括论坛、问答平台、资源库等等。 首先,我想到Biostars,这是一个比较知名的生物信…...
Lumerical INTERCONNECT 中的自相位调制 (SPM)
一、自相位调制的数学介绍 A.非线性薛定谔方程(NLSE): NLSE 是光学中的一个关键方程。它告诉我们光脉冲在具有非线性和色散特性的介质中的行为方式。该方程如下所示: i ∂A/∂z β2/2 ∂A/∂t γ|A|A 0 其中: - …...
每日定投40刀BTC(6)20250227 - 20250302
定投 得而复失 《得而复失》初得明珠喜欲狂,转瞬即逝心彷徨。得失之间悟真谛,淡看浮华守本常。...
leetcode 230. 二叉搜索树中第 K 小的元素
题目如下 数据范围 利用一个全局的计数器每过一个节点就加一,再利用中序遍历的特性(即遍历到的节点是从小到大的)通过代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeN…...
华为hcia——Datacom实验指南——配置手工模式以太网链路聚合
什么是以太网链路聚合(Eth-trunk) 是一种将多个物理链路捆绑在一起,让设备以为是一条大链路,能够增加带宽,增加冗余度,提升可靠性,实现负载平衡。 传输方式有两种 基于数据流传输和基于数据包…...
Metal学习笔记十一:贴图和材质
在上一章中,您设置了一个简单的 Phong 光照模型。近年来,研究人员在基于物理的渲染 (PBR) 方面取得了长足的进步。PBR 尝试准确表示真实世界的着色,真实世界中离开表面的光量小于表面接收的光量。在现实世界中…...
VirtualBox虚拟机MacOS从Big Sur升级到Sequoia(失败)
VirtualBox虚拟机里安装好Big Sur版本,尝试升级到Sequoia,但是最终失败了。 软件升级 直接在系统偏好-软件更新里可以看到提示,提示可以升级到15版本Sequoia 点击同意,看能不能升级到Sequoia吧。升级前先用时光做了备份。 升级…...
*算法中的数据结构(3)
持续更新 1.单调栈 它依旧是⼀个栈结构,只不过⾥⾯存储的数据是递增或者递减的。 2. 单调栈解决的问题 *寻找当前元素左侧,离它最近,并且⽐它⼤的元素在哪; • 寻找当前元素左侧,离它最近,并且⽐它⼩的元素…...
【大模型系列篇】国产开源大模型DeepSeek-V3技术报告解析
DeepSeek-V3技术报告 目录 DeepSeek-V3技术报告 1. 摘要 2. 引言 3. DeepSeek V3 架构 3.1 基础架构 3.1.1. 多头潜在注意力 3.1.2. DeepSeekMoE和无辅助损失的负载均衡 3.2 多令牌预测 4. 基础设施 4.1 计算集群 4.2 训练框架 4.2.1. DualPipe算法与计算通信协同优…...
MyBatisPlus搭建教程
简介 搭建MyBatisPlus2.x 构建项目 配置Maven 引入依赖 springboot <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.alibaba</groupId>&l…...
【商城实战(2)】商城架构设计:从底层逻辑到技术实现
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
数据序列化协议 Protobuf 3 介绍(Go 语言)
Protobuf 3 入门 1. 什么是序列化? 1.1 概念 序列化(Serialization 或 Marshalling) 是指将数据结构或对象的状态转换成可存储或传输的格式。反向操作称为反序列化(Deserialization 或 Unmarshalling),它…...
从芯片到光网络:解密平面光波导技术(PLC)核心优势
关键词:PLC、OFDR、光链路检测 平面光波导技术(Planar Lightwave Circuit, PLC)是一种基于平面波导结构的光学器件制造技术。它通过在平面基底上制作光波导,实现光信号的传输、分路、耦合、调制等功能。PLC技术的核心在于利用光波…...
5分钟快速搭建一个 SpringBoot3 + MyBatis-Plus 工程项目
环境 idea 2023.3.5 jdk 17 mysql 8 创建SpringBoot工程 创建SpringBoot工程,这里有两种方式可选,一种是使用idea提供的Spring Initializr自动创建,一种是通过Maven Archetype手动创建 自动创建SpringBoot工程 使用Spring Initializr创建…...
如何判断https使用了哪个版本的TLS?
互联网各领域资料分享专区(不定期更新): Sheet 正文 一、使用浏览器开发者工具(适合普通用户) 1. Google Chrome 打开目标网站(如 https://example.com)。点击地址栏左侧的 锁形图标。选择 「连接是安全的」 → 「证书信息」。在证书详情中,查看 「技术详细信息」 或 「…...
如何在 NocoBase 中实现 CRM 的线索转化
1. 引言 本教程将一步一步地引导您如何在 NocoBase 中实现 CRM 的商机转化(Opportunity Conversion)功能。我们将介绍如何创建所需的 collections(数据表)、配置数据管理页面、设计转化流程以及设置关联管理,从而帮助…...
StarRocks-fe工程在Cursor中不能识别为Java项目
SR简介 StarRocks 是一款高性能分析型数据库,支持实时、多维度、高并发的数据分析。本指南旨在解决在使用 VSCode 或 Cursor 开发 StarRocks 后端项目时遇到的模块识别问题。 问题描述 使用 Cursor 或 VSCode 打开 StarRocks 的后端工程 fe 时,spark-…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
