简体   繁体   中英

Sending byte array in Netty

I'm using LengthFieldBasedFrameDecoder to send and receive byte[] but client gets error java.nio.channels.ClosedChannelException after it writes.

Here is pipeline factory;

@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;

}

Client write it in this way;

channel.write(eventStr.getBytes());

In this code for debugging purposes data to send is String but I can't use StringDecoder.

Does LenghtFieldBasedDecoder is correct method to send and receive byte[] , if not, how can I do it?

edit:

I found that another thread actually closing the channel so java.nio.channels.ClosedChannelException is solved but I'm still eager to learn best practices for this kind of job.

I see 3 different use cases based on your question:

  1. The incoming bytes represent frames of some particular length that is stored in the frame, you need to capture a frame as byte[length] and transfer it to the user
  2. The incoming bytes represent fixed length frames, you need to capture a frame as byte[length] and transfer it to the user
  3. The incoming bytes do not represent any frames and user can deal with any length byte[] array

In case of (1) the LengthFieldBasedFrameDecoder is a right choice, it allows you to capture a frame based on the length stored in the frame. In case of (2) the FixedLengthFrameDecoder should be enough if you know that all frames have the same size. In case of (3) you do not need any special decoder, all readable bytes could be fetched from incoming ByteBuf and transferred to the next handler, but I'm not sure how useful is that approach in a real application since most probably you'll deal with messages of some particular type/size, Netty does not guarantee how exactly the message will be split, one message can arrive as N different chunks.

Also there is ReplayingDecoder that is useful for cases (1-2) if you want to decode incoming bytes and skip a capturing step.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM