First time working with Netty here, I'm having a bug with my ByteToMessageDecoder class and I'm not able to figure out what's going wrong.
I'm repeatedly sending a fixed length packet from my client to the server like so:
public void sendPacket(Packet packet)
{
ByteBuf buf = Unpooled.wrappedBuffer(packet.getBytes());
future.channel().writeAndFlush(buf);
}
The client pipeline only contains a working LengthFieldPrepender that prepends the length of a short.
My server decoder works properly for a random length of time (usually 30 - 60 seconds) and then starts infinitely looping.
public class TestDecoder extends ByteToMessageDecoder
{
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
{
if (in.readableBytes() < Short.BYTES)
return;
int packetLength = in.readShort();
if (in.readableBytes() < packetLength)
{
in.resetReaderIndex();
return;
}
System.out.println(packetLength + " " + in.readableBytes());
out.add(in.readBytes(packetLength));
}
}
After some time, my decoder gets stuck in an infinite loop where the packetLength is the correct value, but the in.readableBytes() have increased to be greater than the packetLength.
When this happens it seems like the input buffer bytes aren't being read to the output list anymore, so it's stuck infinitely repeating and no longer accepting any new bytes being sent to the server (in.readableBytes() never changes).
What am I doing wrong?
Before int packetLength = in.readShort();
you have to mark read index:
in.markReaderIndex();
Or use a LengthFieldBasedFrameDecoder which is a built-in decoder that splits the received ByteBuf
dynamically by the value of the length field in the message.