Question


I am trying to create a zero-copy application with netty 4.0.10.Final. I have problems with slicing. Here is my decode (problematic) method:

@Override
protected void decode(ChannelHandlerContext chc, ByteBuf bb, List<Object> list) throws Exception {
    int readableBytes = bb.readableBytes();
    if (readableBytes < LENGTH_OF_HEADER) {
        LOGGER.debug("skipping bb - too few data for header: " + readableBytes);
        return;
    }

    int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER);
    LOGGER.debug("length of actual message: {}", length);

    if (readableBytes < length) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("skipping bb - too few data for msg: " +
                    readableBytes + " < " + length);
            LOGGER.debug("bb: " + ByteBufUtils.byteBufToHexString(bb));
        }
        return;
    }
    LOGGER.debug("whole bb: " + ByteBufUtils.byteBufToHexString(bb));
    LOGGER.debug("Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1));

    ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length);
    list.add(messageBuffer);
    bb.skipBytes(length);
    bb.retain();
    LOGGER.debug("BB after slice: " + ByteBufUtils.byteBufToHexString(bb));
}

My application / netty can receive also incomplete messages.

Whole pipeline processing works fine while whole messages are received. My pipeline starts at ServerBootstrap -> ChannelInitializer -> ByteToMessageDecoder -> ByteToMessageDecoder -> MessageToMessageDecoder.

Problem occurs, when a frame with incomplete message arrives.
Typical usecase:
- received frame shorter then expected message (messages have length field in the header)
- received another frame that completes the incomplete message and carries another incomplete message
- slice for complete message is created and incomplete message waits for the rest of its body (all three .byteBufToHexString() logs are correct)
- slice is passed to the next ChannelHandler (which is also ByteToMessageDecoder)
- the data sent inside the sliced-bytebuf has been changed - bytes of incomplete message are used instead of the complete message bytes
- if the complete message is longer than the incomplete one (usually it is), the rest of the complete message bytes is used

Example (bold - complete message, italics - incomplete message):
Original buffer - 01 02 03 04 05 06 07 08 09 0A
Sliced buffer - 01 02 03 04 05 06 07
Next-handler buffer - 08 09 0A 04 05 06 07

This happens only with first "framed" message and the incomplete message. Messages between these two look fine.

Same result with .readSlice().
Copying data works (as the data in copied bytebufs are not shared)

Does anyone see a mistake ? Can anyone help ?

Was it helpful?

Solution

I think this was fixed in Netty 4.0.12.Final as port of this commit: https://github.com/netty/netty/commit/8930cefab8640fa1bef3d1d49f93a23184b1bafe

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top