java - 在 Netty 中发送字节数组

标签 java netty

我正在使用 LengthFieldBasedFrameDecoder 发送和接收 byte[] 但客户端在写入后收到错误 java.nio.channels.ClosedChannelException .

这里是管道工厂;

@Override
public ChannelPipeline getPipeline() throws Exception {

    String charSet = EvamProperties.charSet.get();
    ChannelPipeline pipeline = Channels.pipeline();

    pipeline.addLast("framer", new LengthFieldBasedFrameDecoder(1000000,0,4,0,4));//16KB
    pipeline.addLast("decoder", new OneToOneDecoder() {
        @Override
        protected Object decode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {

            if (!(o instanceof ChannelBuffer)) {
                return o;
            }

            ChannelBuffer buffer = (ChannelBuffer) o;

            int length = buffer.readInt();
            byte[] bytes = new byte[length];
            buffer.readBytes(bytes);

            return bytes;
        }
    });
    pipeline.addLast("encoder", new OneToOneEncoder() {
        @Override
        protected Object encode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {

            if(!(o instanceof byte[])) {
                return o;
            }

            ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
            buffer.writeInt(((byte[]) o).length);
            buffer.writeBytes((byte[])o);

            return buffer;
        }
    });
    pipeline.addLast("handler", new RawEventServerHandler());
    return pipeline;

}

客户端这样写;

channel.write(eventStr.getBytes());

在这段用于调试目的的代码中,要发送的数据是字符串,但我不能使用 StringDecoder。

LenghtFieldBasedDecoder 是否是发送和接收 byte[] 的正确方法,如果不是,我该怎么做?

编辑:

我发现另一个线程实际上关闭了 channel ,因此 java.nio.channels.ClosedChannelException 已解决,但我仍然渴望学习此类工作的最佳实践。

最佳答案

根据您的问题,我看到了 3 种不同的用例:

  1. 传入的字节表示存储在帧中的某些特定长度的帧,您需要将帧捕获为byte[length]并将其传输给用户
  2. 传入的字节表示固定的长度帧,您需要将帧捕获为byte[length]并将其传输给用户
  3. 传入的字节不代表任何帧,用户可以处理任何长度的byte[]数组

在 (1) 的情况下,LengthFieldBasedFrameDecoder 是正确的选择,它允许您根据帧中存储的长度捕获帧。在 (2) 的情况下,如果您知道所有帧都具有相同的大小,则 FixedLengthFrameDecoder 应该足够了。在 (3) 的情况下,您不需要任何特殊的解码器,所有可读字节都可以从传入的 ByteBuf 中获取并传输到下一个处理程序,但我不确定这种方法在实际应用程序 因为很可能你会处理一些特定类型/大小的消息,Netty 不保证消息将如何精确分割,一条消息可以作为 N 个不同的 block 到达。

还有 ReplayingDecoder 如果您想解码传入的字节并跳过捕获步骤,它对情况 (1-2) 很有用。

关于java - 在 Netty 中发送字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33560807/

相关文章:

java - 错误提示找不到符号

java - 在 Java 中将 XML 文档写入文件时出错

java - Spring 数据JPA : one-to-one instantiation problem: PersistentObjectException: detached entity passed to persist

java - NettyIO 断开客户端与服务器的连接

netty - 代表连接到 netty 服务器的客户端

java - 级联 - 合并 2 个聚合

java - 使用 JCache 实现保存条目顺序

java - 使用 Netty 将 websockets 与在 tomcat 中运行的 Spring Web 应用程序集成

java - 如何配置 Netty 以拥有单个工作线程?

java - 15GB 后数据传输速率变慢,用于更大的文件传输