【能用】springboot集成netty,解码器处理数据过长的问题

netty解码器处理数据过长的问题

处理数据过长的详细流程

当第一次 decode 调用时,如果数据不完整,decode 方法会直接返回,Netty 会保留 ByteBuf 中的数据。后续数据到达时,会再次调用 decode 方法,ByteBuf 会累积新到达的数据。
一旦 ByteBuf 中的数据足够完整解析,就会成功解析出 CustomMessage 并添加到 out 列表中,传递给后续的 YourBusinessLogicHandler 进行处理。
这样,通过检查数据的完整性并利用 Netty 的数据累积特性,就可以实现当数据过长时等待全部数据到达后再进行解码操作。你可以根据具体的协议和需求调整 CustomDataDecoder 中的长度检查逻辑,确保对不同长度的数据都能正确处理。
请注意,在实际应用中,可能需要考虑长时间等待数据不到达的情况,可以添加超时机制或其他错误处理机制,以避免资源的无限占用。例如,可以在 ChannelHandlerContext 上使用 channel().close() 关闭连接,或者使用 ctx.fireExceptionCaught() 抛出异常进行异常处理。

解决思路

明确协议格式

确定 dataLen 在数据中的具体位置。假设 dataLen 在 cmdLen 和 cmdPayload 之后,并且 cmdPayload 的长度是由 cmdLen 确定的。
需要先读取 cmdLen,然后读取 cmdPayload,接着根据 cmdPayload 的长度找到 dataLen 的位置。

逐步解析数据

按照协议规定的顺序和长度,逐步从 ByteBuf 中读取相应的数据。

示例代码(Java 和 Netty):

public class TcpMessageDecoderHandler extends ByteToMessageDecoder {
    private static final Logger logger = LoggerFactory.getLogger(TcpHandleServiceImpl.class);

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
        try {
            // 检查是否有足够的字节读取 cmdLen
            if (in.readableBytes() < 2) {
                // 等待更多数据,因为 cmdLen 占 2 字节
                return;
            }

            // 读取 cmdLen(大端序)
            int cmdLen = in.readUnsignedShort();

            // 检查是否有足够的字节读取 cmdPayload
            if (in.readableBytes() < cmdLen) {
                // 数据不完整,重置读指针,等待更多数据
                in.resetReaderIndex();
                return;
            }

            // 读取 cmdPayload
            byte[] cmdPayload = new byte[cmdLen];
            in.readBytes(cmdPayload);
            String cmd = new String(cmdPayload, StandardCharsets.UTF_8);

            // 检查是否有足够的字节读取 dataLen
            if (in.readableBytes() < 2) {
                // 等待更多数据,因为 dataLen 占 2 字节
                in.resetReaderIndex();
                return;
            }

            // 读取 dataLen(大端序)
            int dataLen = in.readUnsignedShort();

            logger.info("可读字节:" + in.readableBytes());
            // 检查是否有足够的字节读取 dataPayload
            if (in.readableBytes() < dataLen) {
                // 数据不完整,重置读指针,等待更多数据
                in.resetReaderIndex();
                return;
            }

            // 读取 dataPayload
            byte[] dataPayload = new byte[dataLen];
            in.readBytes(dataPayload);

            // 在这里可以将 cmd 和 dataPayload 封装到自定义对象中,例如 CustomMessage
            TcpMessage tcpMessage = new TcpMessage(cmd, dataPayload);
            out.add(tcpMessage);
        } catch (Exception e){
            logger.error("读取字节流出错:" + e.getMessage());
            // 重置读指针
            in.resetReaderIndex();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("error:" + cause.getMessage());
    }
}
代码解释

首先检查 ByteBuf 中是否有足够的字节读取 cmdLen,如果不足 2 字节,等待更多数据。
读取 cmdLen,它是 2 字节的大端序数据。
检查是否有足够的字节读取 cmdPayload,如果不足,重置读指针等待更多数据。
读取 cmdPayload 并将其转换为字符串(假设是 UTF-8 编码)。
检查是否有足够的字节读取 dataLen,如果不足,重置读指针等待更多数据。
读取 dataLen,它是 2 字节的大端序数据。
检查是否有足够的字节读取 dataPayload,如果不足,重置读指针等待更多数据。
读取 dataPayload 并存储在字节数组中。
创建 CustomMessage 对象,将 cmd 和 dataPayload 作为成员变量,并将其添加到 out 列表中。

问题

1.如果始终没有接收到足够长度的数据,会卡住

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

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

相关文章

UE5失真材质

渐变材质函数&#xff1a;RadialGradientExponential&#xff08;指数径向渐变&#xff09; 函数使用 UV 通道 0 来产生径向渐变&#xff0c;同时允许用户调整半径和中心点偏移。 用于控制渐变所在的位置及其涵盖 0-1 空间的程度。 基于 0-1 的渐变中心位置偏移。 源自中心的径…

Go语言在实际项目中的应用:从RESTful API到日志监控 (十四)

Go语言在实际项目中的应用&#xff1a;从RESTful API到日志监控 &#x1f680; Go语言&#xff08;又叫Golang&#xff09;作为一种现代化的编程语言&#xff0c;凭借其简洁的语法和强大的性能&#xff0c;已经成为了很多企业技术栈的一部分。在实际项目中&#xff0c;Go不仅仅…

3blue1brow线代笔记

向量 物理&#xff1a;空间中的箭头&#xff0c;长度和方向决定一个向量。只要两者相同&#xff0c;可以任意移动保持不变 计算机&#xff1a;有序的数字列表 &#xff08;数组&#xff09; 数学&#xff1a;向量可以是任何东西&#xff0c;只要保证两个向量相加以及数字与向量…

壁纸样机神器,这个工具适合专业设计师用吗?

壁纸样机神器在一定程度上适合专业设计师使用&#xff0c;但是否适合具体取决于设计师的需求和使用场景&#xff1a; 适合专业设计师的方面 快速实现设计想法&#xff1a;专业设计师在创作过程中&#xff0c;有时需要快速将设计想法变为可视化的效果图&#xff0c;以便进行初…

STM32CUBEIDE FreeRTOS操作教程(十二):std dynamic memory 标准动态内存

STM32CUBEIDE FreeRTOS操作教程&#xff08;十二&#xff09;&#xff1a;std dynamic memory 标准动态内存 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F40…

在线机考|2024华为实习秋招春招编程题(最新)——第3题_PCB印刷电路板布线_300分(八)

题目内容 在PCB印刷电路板设计中,器件之间的连线需要避免线路的阻抗值增大、而且赛件之间还有别的器件和别的干扰源,在布线时我们希望受到的干扰尽量小。现将电路板简化成一个MN的矩阵,每个位置(单元格)的值表示其源干扰度。 如果单元格的值为0,表示此位置没有干扰源;如果单…

1961-2022年中国大陆多干旱指数数据集(SPI/SPEI/EDDI/PDSI/SC-PDSI/VPD)

DOI: 10.5194/essd-2024-270 干旱指数对于评估和管理缺水和农业风险至关重要;然而&#xff0c;现有数据集中缺乏统一的数据基础&#xff0c;导致不一致&#xff0c;对干旱指数的可比性提出了挑战。本研究致力于创建CHM_Drought&#xff0c;这是一个创新且全面的长期气象干旱数…

建造者模式 Builder Pattern

在创建一个对象的时候&#xff0c;构造器参数有点多&#xff0c;而且有些参数还是可选的&#xff0c;再者还有不少同类型的&#xff0c;那就更应该使用 builder 模式了。 使用 Builder 模式的初衷是 把易变性&#xff08;mutability&#xff09;移动到Builder类&#xff0c;而…

【人工智能机器学习基础篇】——深入详解监督学习之模型评估:掌握评估指标(准确率、精确率、召回率、F1分数等)和交叉验证技术

深入详解监督学习之模型评估 在监督学习中&#xff0c;模型评估是衡量模型性能的关键步骤。有效的模型评估不仅能帮助我们理解模型在训练数据上的表现&#xff0c;更重要的是评估其在未见数据上的泛化能力。本文将深入探讨监督学习中的模型评估方法&#xff0c;重点介绍评估指…

Linux(Ubuntu24.04)源码编译安装VTK7.1.1记录

VTK&#xff08;Visualization Toolkit&#xff09;是一个开源的3D可视化开发工具包&#xff0c;用于开发可视化和图形处理应用程序。VTK提供了一系列的算法和工具&#xff0c;用于创建、渲染和处理复杂的3D图形和数据。VTK由C编写&#xff0c;并提供了Python、Java和Tcl等语言…

FICO财务模块在SAP ECC与S4 HANA系统间的差异有哪些?

【SAP系统研究】 #SAP #FICO #ECC #HANA #Oracle #SAP财务 尽管SAP S4/HANA已经发布很久&#xff0c;但使用SAP ECC系统的企业也仍然很多。 这两个系统在FICO模块中有哪些常见的不同呢&#xff1f; 1、数据库表 ①SAP ECC系统 可以在Oracle、IBM DB2等数据库上运行 ②SAP S…

CDPHudi实战-集成spark

[一]使用Spark-shell 1-配置hudi Jar包 [rootcdp73-1 ~]# for i in $(seq 1 6); do scp /opt/software/hudi-1.0.0/packaging/hudi-spark-bundle/target/hudi-spark3.4-bundle_2.12-1.0.0.jar cdp73-$i:/opt/cloudera/parcels/CDH/lib/spark3/jars/; done hudi-spark3.4-bu…

mac m2 安装 docker

文章目录 安装1.下载安装包2.在downloads中打开3.在启动台打开打开终端验证 修改国内镜像地址小结 安装 1.下载安装包 到官网下载适配的安装包&#xff1a;https://www.docker.com/products/docker-desktop/ 2.在downloads中打开 拖过去 3.在启动台打开 选择推荐设置 …

Power BI如何连接Azure Databricks数据源?

故事背景: 近期有朋友询问&#xff0c;自己公司有一些项目使用了Azure Databricks用于数据存储。如何使用Power BI Desktop桌面开发软件连接Azure Databricks的数据源呢&#xff1f; 解决方案: 其实Power BI是提供了连接Azure Databricks数据源的选项的&#xff0c;只是配置…

Python入门教程 —— 进制转换

找其他编译器&#xff0c;系统解释器&#xff0c;这样速度会快很多。 进制 现代的计算机和依赖计算机的设备里都用到二进制(即0和1)来保存和表示数据&#xff0c;一个二进制表示一个比特(Bit)。 在二进制的基础上&#xff0c;计算机还支持八进制和十六进制这两种进制。 除了…

HTML5新特性|05 CSS3边框CSS3背景

CSS3边框 1、CSS3边框: 通过CSS3&#xff0c;您能够创建圆角边框&#xff0c;向矩形添加阴影&#xff0c;使用图片来绘制边框-并且不需使用设计软件&#xff0c;比如PhotoShop。 属性: border-radius 圆角box-shadow:水平阴影 垂直阴影 阴影的清晰度 阴影的大小 阴影的颜色…

《Vue3实战教程》26:Vue3Transition

如果您有疑问&#xff0c;请观看视频教程《Vue3实战教程》

SpringCloudAlibaba实战入门之Sentinel服务降级和服务熔断(十五)

一、Sentinel概述 1、Sentinel是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 一句话概括:sentinel即Hystrix的替代品,官网: https://sentinelguard.io/zh…

Scratch教学作品 | 白水急流——急流勇进,挑战反应极限! ‍♂️

今天为大家推荐一款刺激又好玩的Scratch冒险作品——《白水急流》&#xff01;由AgentFransidium制作&#xff0c;这款作品将带你体验惊险的急流救援任务&#xff0c;帮助那位“睡着的疯狂人”安全穿越湍急水域&#xff01;想要挑战自己的反应极限&#xff1f;快来试试吧&#…

计算机毕业设计Django+Tensorflow音乐推荐系统 音乐可视化 卷积神经网络CNN LSTM音乐情感分析 机器学习 深度学习 Flask

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…