3

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.

2
  • 1
    First if using Netty 4.x, you need to flush somewhere (for instance writeAndFlush). Second, the ClosedChannelException means you try to read or write from / to the channel while it is already closed. There may be several reasons. What is your RawEventServerHandler on both sides client and server ? Commented Nov 6, 2015 at 7:14
  • thanks man see my edit. Commented Nov 6, 2015 at 7:15

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.