Netty接收超长TCP数据时 使用按行分隔Decoder无法正确解码的问题解决

使用Netty实现的tcp服务端,由于tcp是流式传输的,故需要选用一个解码器对流式消息进行解码和包分隔,以防收到不正确的包。例如LineBasedFrameDecoder,LengthFieldBasedFrameDecoder,DelimiterBasedFrameDecoder等常用解码器。

++需求是收到的消息最长长度限制在50M内,且没有固定的消息头,每次接收消息又不一定在结尾存在固定的换行符,所以现有的解码器都不足够满足需求。++

LineBasedFrameDecoder在收到数据后累加在内存变量中,然后检测到固定的换行符时将消息截断并发给下一个handler。但如果一直没有收到换行符时,则会在channelinactive时,丢弃之前接收到的所有消息。但实际上他会调用一次decodeLast方法,再执行一次decode逻辑。为了解决这个问题,可以通过自定义子类覆盖其decodeLast方法,实现自定义的逻辑。

为了解决数据丢弃问题,该解码器在执行到此方法时,检测最后一个字节是不是换行符,如果不是换行符则手动增加一个换行符到其中,此时就肯定会被decode方法将之前接收到的数据组成一个包。

java 复制代码
 /**
     * 基于换行符的自定义解码器
     * 解决了当流传输结束时,最后一个字符不是换行符无法解析的问题
     * 当最后一个字符不是换行符时,增加一个换行符
     */
    private static class CustomLineBasedFrameDecoder extends LineBasedFrameDecoder {

        private static final byte LINE_DELIMITER = '\n';

        public CustomLineBasedFrameDecoder(int maxLength) {
            super(maxLength);
        }

        public CustomLineBasedFrameDecoder(int maxLength, boolean stripDelimiter, boolean failFast) {
            super(maxLength, stripDelimiter, failFast);
        }

        @Override
        protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
            if (in.isReadable()) {
                //查看最后一个字节是不是换行符 如果不是则增加一个换行符
                byte lastByte = in.getByte(in.writerIndex() - 1);
                if (lastByte != LINE_DELIMITER) {
                    if (in.isWritable()) {
                        in.writeByte(LINE_DELIMITER);
                    } else {
                        //未测试代码块
                        ByteBuf old = in;
                        //如果不可写 则重新分配一个缓冲区  
                        in = MERGE_CUMULATOR.cumulate(ctx.alloc(), internalBuffer(), Unpooled.buffer(1).writeByte(LINE_DELIMITER));
                        old.clear();
                    }
                }
            }
            super.decodeLast(ctx, in, out);
        }
    }
相关推荐
虎头金猫1 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
wuyk5552 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
XUEYUAN52122 天前
ASN 自治系统号风控:平台如何通过 IP 所属自治域批量识别代理流量
python·网络协议·http·网络安全·socks5
QYRdata2 天前
年均增速24.2%!机器人数据湖未来六年增长动能强劲
网络·机器人·服务发现
CHENKONG_CK2 天前
破解制鞋打磨痛点:RFID赋能去毛刺工序自动化升级
网络·单片机·嵌入式硬件·网络协议·tcp/ip
chshang19922 天前
工业路由器是什么?浅谈5G工业网络中的IR602
网络·物联网·5g·智能路由器
萧瑟余晖2 天前
Netty 核心组件与 Reactor 模型详解
网络·架构
ITxiaobing20232 天前
IP 定位服务选型指南:从准确率到工程落地的技术考察
linux·服务器·网络
wuyk5552 天前
【Socket 进阶之路】第 9 章 Linux 网络服务量产稳定性优化|心跳保活、TIME_WAIT、SO_LINGER、内存池、断线重连、完整异常防护框架
linux·服务器·开发语言·网络·物联网
z落落2 天前
C#UDP+串口服务端+UDP 客户端(含 CRC16 校验)
网络·网络协议·udp