当前位置: 首页 > 知识库问答 >
问题:

Netty LengthFieldPrepender和LengthFieldBasedFrameDecoder的正确用法

闽涵蓄
2023-03-14

我有一个使用Netty 3.6.6的应用程序。我使用Netty将随机数据包从客户端发送到服务器。

发送方使用此管道:

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() {
                return Channels.pipeline(
                        new LengthFieldPrepender(4) );
            }
    });

我用ChannelBuffer包装我的数据包数据,我希望处理程序添加4字节长度,以便接收者可以知道数据包的开始和结束位置。

接收器使用:

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                    return Channels.pipeline(
                            new NettyReceiveHandler(listener));
            }
        });


    public class NettyReceiveHandler extends LengthFieldBasedFrameDecoder {
        @Override
        protected Object decode(ChannelHandlerContext ctx, Channel channel,
                ChannelBuffer buffer) throws Exception {
            ChannelBuffer decodedBuffer = (ChannelBuffer) super.decode(ctx, channel, buffer);
            if(decodedBuffer == null)
            {
                return null; // not ready yet
            }
            listener.handleObject(decodedBuffer);   
            return null;    // no upstream
        }

        public NettyReceiveHandler(NettyRecvListener listener) {
            super(THREEMiB, 0, 4, 0, 4); 
            this.listener = listener;       
        }

        private static final Logger logger = Logger.getLogger(
                NettyReceiveHandler.class.getName());

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
            logger.severe("Unexpected exception from downstream." + e.getCause());
            e.getChannel().close();
        }

        private final NettyRecvListener listener;
        private static final int THREEMiB = 3*1024*1024;
    }

一切似乎都按预期工作。发送方一个接一个地发送随机大小的信道缓冲区,接收方以相同的顺序接收相同的信道缓冲器

现在我的问题是:

1.When我向通道写入一个大的ChannelBuffer,它会被分解成几个写入。例如,我在测试日志中看到了这一点。

WARNING: The pipeline contains no upstream handlers; discarding: [id: 0xa1b55c95, /127.0.0.1:52359 => localhost/127.0.0.1:9991] WRITTEN_AMOUNT: 131071

假设我发送两个1mb的缓冲区(bufferA和bufferB ),每个写操作大致分为8个写操作——buffer a1、bufferA2、...缓冲器1、缓冲器2、...如果bufferA4写失败(由于负载太大或者接收者错误地在回调中花费了太多时间),成帧是否会中断?也就是说,在接收器端,缓冲区错误地由缓冲区1、缓冲区2、缓冲区3、缓冲区5、缓冲区6、缓冲区7、缓冲区8、缓冲区1组成。

有没有关于不破坏框架的保证。

2.是否总是在NettyReceiveHandler::decode中返回null正确的方法,因为我没有任何上游处理程序?

谢谢你的任何帮助。

共有1个答案

荣俊杰
2023-03-14

假设有传输控制协议,那么你的大写入不会被丢弃。Netty会将数据排队,直到它可以被写入。Netty可能会通过引发INTEREST_OPS事件来表明它的写入队列已满,但它不会阻止你排队更多的数据。

就我个人而言,我会以不同的方式处理这件事。我不会扩展LengthFieldBasedFrameDecoder,而是创建一个带有2个处理程序的管道——一个标准的LengthFieldBasedFrameDecoder和一个NettyReceiveHandler。然后,您所要做的就是覆盖messageReceived并使用e.getMessage()调用您的侦听器(或者您调用的任何消息事件参数)。不需要调用LengthFieldBasedFrameDecoder的decode方法,也不需要担心是否需要返回null。只是处理信息。

 类似资料:
  • 这可能是一个新问题,所以我会马上说出来。这是我第一次创建IDisposable类,我想确保我正确创建了我的类,正确调用了它,并正确处理了它。谢谢! 这就是我所说的。

  • 问题内容: 我该如何纠正这个问题,以便我的MySQL代码正常工作。 这是我的MySQL代码,给了我这个问题。 问题答案: 根据MySQL文档UPDATE: 对于多表语法,UPDATE更新满足条件的table_references中命名的每个表中的行。在这种情况下,不能使用ORDER BY和LIMIT。

  • 问题内容: 我正在阅读有关PyQt5的一些文档,以提出一种简单的信号插槽机制。由于设计方面的考虑,我停了下来。 考虑以下代码: 为了跟踪对滑块所做的更改,我仅打印并记录所做的更改。我对代码不满意的是,我需要调用三次插槽以将相同的信息发送到3个不同的插槽。 是否可以创建自己的将整数发送到单个插槽的函数。插槽功能又会发出需要进行的更改吗? 也许我不完全了解它的目的,因为在PyQt Signal-Slo

  • 我用PHPass散列密码已经很久了。我承认仍然有一些我不完全理解(或忽略)的东西来正确地散列密码,所以今天我查看了所有我能找到的关于它的信息。 回顾PHPass文档,我已经进入了这个: 除了实际的哈希之外,phpass 在对新密码或密码进行哈希处理时会透明地生成随机 salt,并将哈希类型、salt 和密码拉伸迭代计数编码到它返回的“hash 编码字符串”中。当phpass根据存储的哈希对密码或密

  • 问题内容: 我刚刚开始使用BoneCP,并从作者站点中提取了示例JDBC代码。 我有一个名为getConnection()的函数,该函数返回一个片段: 现在,我的问题是:1)使用完上述函数返回的连接后,是否将其返回到池中,还是完全关闭连接,我该调用connection.close()吗?如何将连接返回池? 2)如何在应用程序退出时清理池?我结束时会调用connectionPool.shutdown