Top Description Fields Constructors Methods
io.netty.handler.codec

public Class LengthFieldBasedFrameDecoder

extends ByteToMessageDecoder
Class Inheritance
Known Direct Subclasses
io.netty.handler.codec.marshalling.MarshallingDecoder, io.netty.handler.codec.serialization.ObjectDecoder
Static Imports
io.netty.util.internal.ObjectUtil.checkNotNull, .ObjectUtil.checkPositive, .ObjectUtil.checkPositiveOrZero

A decoder that splits the received ByteBufs dynamically by the value of the length field in the message. It is particularly useful when you decode a binary message which has an integer header field that represents the length of the message body or the whole message.

LengthFieldBasedFrameDecoder has many configuration parameters so that it can decode any message with a length field, which is often seen in proprietary client-server protocols. Here are some example that will give you the basic idea on which option does what.

2 bytes length field at offset 0, do not strip header

The value of the length field in this example is 12 (0x0C) which represents the length of "HELLO, WORLD". By default, the decoder assumes that the length field represents the number of the bytes that follows the length field. Therefore, it can be decoded with the simplistic parameter combination.
lengthFieldOffset   = 0
lengthFieldLength   = 2
lengthAdjustment    = 0
initialBytesToStrip = 0 (= do not strip header)

BEFORE DECODE (14 bytes)         AFTER DECODE (14 bytes)
+--------+----------------+      +--------+----------------+
| Length | Actual Content |----->| Length | Actual Content |
| 0x000C | "HELLO, WORLD" |      | 0x000C | "HELLO, WORLD" |
+--------+----------------+      +--------+----------------+

2 bytes length field at offset 0, strip header

Because we can get the length of the content by calling ByteBuf#readableBytes(), you might want to strip the length field by specifying initialBytesToStrip. In this example, we specified 2, that is same with the length of the length field, to strip the first two bytes.
lengthFieldOffset   = 0
lengthFieldLength   = 2
lengthAdjustment    = 0
initialBytesToStrip = 2 (= the length of the Length field)

BEFORE DECODE (14 bytes)         AFTER DECODE (12 bytes)
+--------+----------------+      +----------------+
| Length | Actual Content |----->| Actual Content |
| 0x000C | "HELLO, WORLD" |      | "HELLO, WORLD" |
+--------+----------------+      +----------------+

2 bytes length field at offset 0, do not strip header, the length field represents the length of the whole message

In most cases, the length field represents the length of the message body only, as shown in the previous examples. However, in some protocols, the length field represents the length of the whole message, including the message header. In such a case, we specify a non-zero lengthAdjustment. Because the length value in this example message is always greater than the body length by 2, we specify -2 as lengthAdjustment for compensation.
lengthFieldOffset   =  0
lengthFieldLength   =  2
lengthAdjustment    = -2 (= the length of the Length field)
initialBytesToStrip =  0

BEFORE DECODE (14 bytes)         AFTER DECODE (14 bytes)
+--------+----------------+      +--------+----------------+
| Length | Actual Content |----->| Length | Actual Content |
| 0x000E | "HELLO, WORLD" |      | 0x000E | "HELLO, WORLD" |
+--------+----------------+      +--------+----------------+

3 bytes length field at the end of 5 bytes header, do not strip header

The following message is a simple variation of the first example. An extra header value is prepended to the message. lengthAdjustment is zero again because the decoder always takes the length of the prepended data into account during frame length calculation.
lengthFieldOffset   = 2 (= the length of Header 1)
lengthFieldLength   = 3
lengthAdjustment    = 0
initialBytesToStrip = 0

BEFORE DECODE (17 bytes)                      AFTER DECODE (17 bytes)
+----------+----------+----------------+      +----------+----------+----------------+
| Header 1 |  Length  | Actual Content |----->| Header 1 |  Length  | Actual Content |
|  0xCAFE  | 0x00000C | "HELLO, WORLD" |      |  0xCAFE  | 0x00000C | "HELLO, WORLD" |
+----------+----------+----------------+      +----------+----------+----------------+

3 bytes length field at the beginning of 5 bytes header, do not strip header

This is an advanced example that shows the case where there is an extra header between the length field and the message body. You have to specify a positive lengthAdjustment so that the decoder counts the extra header into the frame length calculation.
lengthFieldOffset   = 0
lengthFieldLength   = 3
lengthAdjustment    = 2 (= the length of Header 1)
initialBytesToStrip = 0

BEFORE DECODE (17 bytes)                      AFTER DECODE (17 bytes)
+----------+----------+----------------+      +----------+----------+----------------+
|  Length  | Header 1 | Actual Content |----->|  Length  | Header 1 | Actual Content |
| 0x00000C |  0xCAFE  | "HELLO, WORLD" |      | 0x00000C |  0xCAFE  | "HELLO, WORLD" |
+----------+----------+----------------+      +----------+----------+----------------+

2 bytes length field at offset 1 in the middle of 4 bytes header, strip the first header field and the length field

This is a combination of all the examples above. There are the prepended header before the length field and the extra header after the length field. The prepended header affects the lengthFieldOffset and the extra header affects the lengthAdjustment. We also specified a non-zero initialBytesToStrip to strip the length field and the prepended header from the frame. If you don't want to strip the prepended header, you could specify 0 for initialBytesToSkip.
lengthFieldOffset   = 1 (= the length of HDR1)
lengthFieldLength   = 2
lengthAdjustment    = 1 (= the length of HDR2)
initialBytesToStrip = 3 (= the length of HDR1 + LEN)

BEFORE DECODE (16 bytes)                       AFTER DECODE (13 bytes)
+------+--------+------+----------------+      +------+----------------+
| HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content |
| 0xCA | 0x000C | 0xFE | "HELLO, WORLD" |      | 0xFE | "HELLO, WORLD" |
+------+--------+------+----------------+      +------+----------------+

2 bytes length field at offset 1 in the middle of 4 bytes header, strip the first header field and the length field, the length field represents the length of the whole message

Let's give another twist to the previous example. The only difference from the previous example is that the length field represents the length of the whole message instead of the message body, just like the third example. We have to count the length of HDR1 and Length into lengthAdjustment. Please note that we don't need to take the length of HDR2 into account because the length field already includes the whole header length.
lengthFieldOffset   =  1
lengthFieldLength   =  2
lengthAdjustment    = -3 (= the length of HDR1 + LEN, negative)
initialBytesToStrip =  3

BEFORE DECODE (16 bytes)                       AFTER DECODE (13 bytes)
+------+--------+------+----------------+      +------+----------------+
| HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content |
| 0xCA | 0x0010 | 0xFE | "HELLO, WORLD" |      | 0xFE | "HELLO, WORLD" |
+------+--------+------+----------------+      +------+----------------+
See Also
LengthFieldPrepender

Field Summary

Modifier and TypeField and Description
private final ByteOrder
private long
private boolean
private final boolean
private int
private final int
private final int
private final int
private final int
private final int
private final int
private long
Inherited from io.netty.handler.codec.ByteToMessageDecoder:
COMPOSITE_CUMULATORcumulationMERGE_CUMULATOR

Constructor Summary

AccessConstructor and Description
public
LengthFieldBasedFrameDecoder(int
the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.
maxFrameLength
,
int
the offset of the length field
lengthFieldOffset
,
int
the length of the length field
lengthFieldLength
)

Creates a new instance.

public
LengthFieldBasedFrameDecoder(int
the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.
maxFrameLength
,
int
the offset of the length field
lengthFieldOffset
,
int
the length of the length field
lengthFieldLength
,
int
the compensation value to add to the value of the length field
lengthAdjustment
,
int
the number of first bytes to strip out from the decoded frame
initialBytesToStrip
)

Creates a new instance.

public
LengthFieldBasedFrameDecoder(int
the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.
maxFrameLength
,
int
the offset of the length field
lengthFieldOffset
,
int
the length of the length field
lengthFieldLength
,
int
the compensation value to add to the value of the length field
lengthAdjustment
,
int
the number of first bytes to strip out from the decoded frame
initialBytesToStrip
,
boolean
If true, a TooLongFrameException is thrown as soon as the decoder notices the length of the frame will exceed maxFrameLength regardless of whether the entire frame has been read. If false, a TooLongFrameException is thrown after the entire frame that exceeds maxFrameLength has been read.
failFast
)

Creates a new instance.

public
LengthFieldBasedFrameDecoder(ByteOrder
the ByteOrder of the length field
byteOrder
,
int
the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.
maxFrameLength
,
int
the offset of the length field
lengthFieldOffset
,
int
the length of the length field
lengthFieldLength
,
int
the compensation value to add to the value of the length field
lengthAdjustment
,
int
the number of first bytes to strip out from the decoded frame
initialBytesToStrip
,
boolean
If true, a TooLongFrameException is thrown as soon as the decoder notices the length of the frame will exceed maxFrameLength regardless of whether the entire frame has been read. If false, a TooLongFrameException is thrown after the entire frame that exceeds maxFrameLength has been read.
failFast
)

Creates a new instance.

Method Summary

Modifier and TypeMethod and Description
protected final void
decode(ChannelHandlerContext ctx, ByteBuf
the ByteBuf from which to read data
in
,
List<Object>
the List to which decoded messages should be added
out
)

Implements abstract io.netty.handler.codec.ByteToMessageDecoder.decode.

Decode the from one ByteBuf to an other.
protected Object

Returns:

frame the ByteBuf which represent the frame or null if no frame could be created.
decode
(ChannelHandlerContext ctx, ByteBuf
the ByteBuf from which to read data
in
)

Create a frame out of the ByteBuf and return it.

private void
private void
exceededFrameLength(ByteBuf in, long frameLength)

protected ByteBuf
extractFrame(ChannelHandlerContext ctx, ByteBuf buffer, int index, int length)

Extract the sub-region of the specified buffer.

private void
fail(long frameLength)

private void
failIfNecessary(boolean firstDetectionOfTooLongFrame)

private static void
failOnFrameLengthLessThanInitialBytesToStrip(ByteBuf in, long frameLength, int initialBytesToStrip)

private static void
failOnFrameLengthLessThanLengthFieldEndOffset(ByteBuf in, long frameLength, int lengthFieldEndOffset)

private static void
failOnNegativeLengthField(ByteBuf in, long frameLength, int lengthFieldEndOffset)

protected long
getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order)

Decodes the specified region of the buffer into an unadjusted frame length.

Inherited from io.netty.handler.codec.ByteToMessageDecoder:
actualReadableBytescallDecodechannelInactivechannelInputClosedchannelReadchannelReadCompletedecodeLastdecodeRemovalReentryProtectiondiscardSomeReadBytesexpandCumulationfireChannelReadfireChannelReadhandlerRemovedhandlerRemoved0internalBufferisSingleDecodesetCumulatorsetDiscardAfterReadssetSingleDecodeuserEventTriggered

Field Detail

byteOrderback to summary
private final ByteOrder byteOrder
bytesToDiscardback to summary
private long bytesToDiscard
discardingTooLongFrameback to summary
private boolean discardingTooLongFrame
failFastback to summary
private final boolean failFast
frameLengthIntback to summary
private int frameLengthInt
initialBytesToStripback to summary
private final int initialBytesToStrip
lengthAdjustmentback to summary
private final int lengthAdjustment
lengthFieldEndOffsetback to summary
private final int lengthFieldEndOffset
lengthFieldLengthback to summary
private final int lengthFieldLength
lengthFieldOffsetback to summary
private final int lengthFieldOffset
maxFrameLengthback to summary
private final int maxFrameLength
tooLongFrameLengthback to summary
private long tooLongFrameLength

Constructor Detail

LengthFieldBasedFrameDecoderback to summary
public LengthFieldBasedFrameDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength)

Creates a new instance.

Parameters
maxFrameLength:int

the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.

lengthFieldOffset:int

the offset of the length field

lengthFieldLength:int

the length of the length field

LengthFieldBasedFrameDecoderback to summary
public LengthFieldBasedFrameDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip)

Creates a new instance.

Parameters
maxFrameLength:int

the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.

lengthFieldOffset:int

the offset of the length field

lengthFieldLength:int

the length of the length field

lengthAdjustment:int

the compensation value to add to the value of the length field

initialBytesToStrip:int

the number of first bytes to strip out from the decoded frame

LengthFieldBasedFrameDecoderback to summary
public LengthFieldBasedFrameDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast)

Creates a new instance.

Parameters
maxFrameLength:int

the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.

lengthFieldOffset:int

the offset of the length field

lengthFieldLength:int

the length of the length field

lengthAdjustment:int

the compensation value to add to the value of the length field

initialBytesToStrip:int

the number of first bytes to strip out from the decoded frame

failFast:boolean

If true, a TooLongFrameException is thrown as soon as the decoder notices the length of the frame will exceed maxFrameLength regardless of whether the entire frame has been read. If false, a TooLongFrameException is thrown after the entire frame that exceeds maxFrameLength has been read.

LengthFieldBasedFrameDecoderback to summary
public LengthFieldBasedFrameDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip, boolean failFast)

Creates a new instance.

Parameters
byteOrder:ByteOrder

the ByteOrder of the length field

maxFrameLength:int

the maximum length of the frame. If the length of the frame is greater than this value, TooLongFrameException will be thrown.

lengthFieldOffset:int

the offset of the length field

lengthFieldLength:int

the length of the length field

lengthAdjustment:int

the compensation value to add to the value of the length field

initialBytesToStrip:int

the number of first bytes to strip out from the decoded frame

failFast:boolean

If true, a TooLongFrameException is thrown as soon as the decoder notices the length of the frame will exceed maxFrameLength regardless of whether the entire frame has been read. If false, a TooLongFrameException is thrown after the entire frame that exceeds maxFrameLength has been read.

Method Detail

decodeback to summary
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception

Implements abstract io.netty.handler.codec.ByteToMessageDecoder.decode.

Doc from io.netty.handler.codec.ByteToMessageDecoder.decode.

Decode the from one ByteBuf to an other. This method will be called till either the input ByteBuf has nothing to read when return from this method or till nothing was read from the input ByteBuf.

Parameters
ctx:ChannelHandlerContext

the ChannelHandlerContext which this ByteToMessageDecoder belongs to

in:ByteBuf

the ByteBuf from which to read data

out:List<Object>

the List to which decoded messages should be added

Annotations
@Override
Exceptions
Exception:
is thrown if an error occurs
decodeback to summary
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception

Create a frame out of the ByteBuf and return it.

Parameters
ctx:ChannelHandlerContext

the ChannelHandlerContext which this ByteToMessageDecoder belongs to

in:ByteBuf

the ByteBuf from which to read data

Returns:Object

frame the ByteBuf which represent the frame or null if no frame could be created.

discardingTooLongFrameback to summary
private void discardingTooLongFrame(ByteBuf in)
exceededFrameLengthback to summary
private void exceededFrameLength(ByteBuf in, long frameLength)
extractFrameback to summary
protected ByteBuf extractFrame(ChannelHandlerContext ctx, ByteBuf buffer, int index, int length)

Extract the sub-region of the specified buffer.

failback to summary
private void fail(long frameLength)
failIfNecessaryback to summary
private void failIfNecessary(boolean firstDetectionOfTooLongFrame)
failOnFrameLengthLessThanInitialBytesToStripback to summary
private static void failOnFrameLengthLessThanInitialBytesToStrip(ByteBuf in, long frameLength, int initialBytesToStrip)
failOnFrameLengthLessThanLengthFieldEndOffsetback to summary
private static void failOnFrameLengthLessThanLengthFieldEndOffset(ByteBuf in, long frameLength, int lengthFieldEndOffset)
failOnNegativeLengthFieldback to summary
private static void failOnNegativeLengthField(ByteBuf in, long frameLength, int lengthFieldEndOffset)
getUnadjustedFrameLengthback to summary
protected long getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order)

Decodes the specified region of the buffer into an unadjusted frame length. The default implementation is capable of decoding the specified region into an unsigned 8/16/24/32/64 bit integer. Override this method to decode the length field encoded differently. Note that this method must not modify the state of the specified buffer (e.g. readerIndex, writerIndex, and the content of the buffer.)

Exceptions
DecoderException:
if failed to decode the specified region