You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Netty同时发送命令与文件?解码异常及文件缺失问题求助

如何用Netty同时发送命令对象与文件ByteBuf?

我现在遇到了一个Netty的问题:不清楚自己操作里的错误,想知道怎么用Netty同时发送命令和文件。先说说我的管道配置:

客户端管道配置

pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null))); //入站
pipeline.addLast(new ObjectEncoder()); //出站
pipeline.addLast(new ChunkedWriteHandler()); //出站
pipeline.addLast(new FileSenderHandler()); //入站(响应中写入)
pipeline.addLast(new FileInfoSenderHandler()); //出站

服务端管道配置

pipeline.addLast(new ObjectEncoder()); //出站
pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null))); //入站
pipeline.addLast(new FileReceiverHandler()); //入站
pipeline.addLast(new FileInfoReceiverHandler()); //入站(响应中写入)

我的操作逻辑是:发送文件前先发送FileInfo命令对象,告知服务端即将传输该命令描述的文件,随后发送文件本身(用ByteBuf)。但问题来了,ByteBuf也会经过ObjectDecoder,Java处理第一个数据块时直接抛出异常:

2021-10-09 01:26:02 WARN DefaultChannelPipeline:1152 - 触发了exceptionCaught()事件,且该事件已到达管道尾部。这通常意味着管道中的最后一个处理器未处理该异常。
io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 1048576: 4292411364 - discarded
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:503)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:489)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.exceededFrameLength(LengthFieldBasedFrameDecoder.java:376)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:419)
at io.netty.handler.codec.serialization.ObjectDecoder.decode(ObjectDecoder.java:69)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:332)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:508)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:447)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)

如果我重写decode()方法并添加日志,能看到文件传输没结束时,每个数据块都会经过ObjectDecoder并被解码为null,后续数据块倒是不会抛出异常。

已尝试的解决方法

  • 在ObjectDecoder构造方法里设置maxObjectSize = Integer.MAX_VALUE,但问题依然存在;
  • 重写decode()方法添加条件判断:
    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        System.out.println("decode()");
        Object o = super.decode(ctx, in);
        System.out.println(o);
        if(o == null){
            System.out.println(in);
            return in;
        }
        return o;
    }
    
    结果文件会缺失2048字节;
  • 通过代码动态修改管道(根据连接状态删除/添加ObjectDecoder),服务端能正常接收文件,但我不确定这个方案是不是正确的。

我现在怀疑是不是自己的逻辑有根本性错误?已经查了几乎所有相关文档,耗了两周时间还是没解决。想问问我还需要学习哪些相关内容?恳请大家帮忙,谢谢!

内容的提问来源于stack exchange,提问作者Самый Важный

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:52:50