I have one client connected to a server. The communication in the TCP session is bidirectional. If I try to send multiple messages simultaneously from the sever to the client they are mixed up in one array. The message is already corrupted when it reaches the ByteArrayDecoder. Here is my pipeline:
ChannelPipeline channelPipeline = ch.pipeline();
channelPipeline.addLast("byteArrayEncoder", new ByteArrayEncoder());
channelPipeline.addLast("myRequestEncoder", new MyRequestEncoder());
channelPipeline.addLast("mySecondEncoder", new MySecondEncoder());
channelPipeline.addLast("byteArraydDecoder", new ByteArrayDecoder());
channelPipeline.addLast("myResponseDecoder", new MyResponseDecoder());
channelPipeline.addLast("mySecondDecoder", new MySecondDecoder());
channelPipeline.addLast("mytHandler", myHandler);
For example I have noticed that the byte array in ByteArrayDecoder has length more than 500 instead of 230. And I have seen that the contents of the array are corresponding to two or more messages that have been concatenated.
I have only one channel. I have tried to use more than one EventExecutorGroup in the pipeline but this keeps happening and I end up to miss several inbound messages.
However with 1tps everything seems to work OK.
Is netty supposed to have such behavior? Am I missing anything?
TCP is a stream based protocol, you application should work from that concept. Netty also receives the bytes as a stream from the networking layer, and its the job of the application to convert the stream of bytes in something useful.
You are failing to correctly convert the incoming streaming bytes in correct blocks of data that your application can handle.
There are multiple ways to introduce a "reframer" for the bytes:
If every packet is a fixed length, you can just read X
amount of bytes, and use that as a simple framing solution, this is really simple using netty:
channelPipeline.addLast("framer", new FixedLengthFrameDecoder(512));
This splits all the incoming bytes up in blocks of 512 bytes.
The arguments to FixedLengthFrameDecoder
are:
Instead of difficulty making every packet the same size, you can also add a length to a packet, so you can split the packets later. Netty also comes with useful utility classes for this:
channelPipeline.addLast("framer", new LengthFieldBasedFrameDecoder(Short.MAX_VALUE,0,2,0,2));
channelPipeline.addLast("framer-prepender", new LengthFieldPrepender(2, false));
The arguments for LengthFieldBasedFrameDecoder
are:
The arguments for LengthFieldPrepender
are:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With