上一节中提到了对象反序列化解析器ObjectDecoder,ObjectDecoder是继承自LengthFieldBasedFrameDecoder,LengthFieldBasedFrameDecoder是Netty通用的拆包器
LengthFieldBasedFrameDecoder用法
LengthFieldBasedFrameDecoder源码解释中是这么说的:
通过长度域lengthFieldLength对ByteBuf进行动态拆分的decoder,特别适合当有一个int做了消息包体头部进行反序列化
LengthFieldBasedFrameDecoder有很多配置参数所以可以对任何指定长度域lengthFieldLength的消息进行反序列化,所以经常用户客户端和服务端的通信协议。
LengthFieldBasedFrameDecoder的几个重要参数:
lengthFiledLength: 长度域大小
maxFrameLength:最大帧长度,即单个包最大的长度
lengthFieldOffset:表示数据长度字段开始的偏移量
lengthAdjustment:长度调整值
initialBytesToStrip:表示从整个包第一个字节开始,向后忽略的字节数
1、基于长度的拆包
长度域2个字节,偏移量0,initialBytesToStrip为0
2、过滤包头Header,只获取包体数据
lengthFieldLength = 2 //数据长度为2个字节
initialBytesToStrip=2 //等于数据的长度,意思就是跳过数据长度字节
lengthFieldOffset=0 //偏移量为0
3、lengthFieldLength代表数据Header+Body的长度,
4、基于可调整长度的拆包
总之,反序列首先会跳过initialBytesToStrip个字节读取buyBuf,lengthAdjustment表示长度域后还有多少个字节才是真正的数据长度。lengthFieldOffset表示还有多少偏移才是真正的长度域
源码分析
构造函数
public LengthFieldBasedFrameDecoder(
ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,
int lengthAdjustment, int initialBytesToStrip, boolean failFast) {
if (byteOrder == null) {
throw new NullPointerException("byteOrder");
}
if (maxFrameLength <= 0) {
throw new IllegalArgumentException(
"maxFrameLength must be a positive integer: " +
maxFrameLength);
}
if (lengthFieldOffset < 0) {
throw new IllegalArgumentException(
"lengthFieldOffset must be a non-negative integer: " +
lengthFieldOffset);
}
if (initialBytesToStrip < 0) {
throw new IllegalArgumentException(
"initialBytesToStrip must be a non-negative integer: " +
initialBytesToStrip);
}
if (lengthFieldOffset > maxFrameLength - lengthFieldLength) {
throw new IllegalArgumentException(
"maxFrameLength (" + maxFrameLength + ") " +
"must be equal to or greater than " +
"lengthFieldOffset (" + lengthFieldOffset + ") + " +
"lengthFieldLength (" + lengthFieldLength + ").");
}
this.byteOrder = byteOrder;
this.maxFrameLength = maxFrameLength;
this.lengthFieldOffset = lengthFieldOffset;
this.lengthFieldLength = lengthFieldLength;
this.lengthAdjustment = lengthAdjustment;
lengthFieldEndOffset = lengthFieldOffset + lengthFieldLength;
this.initialBytesToStrip = initialBytesToStrip;
this.failFast = failFast;
}
lengthFieldEndOffset = lengthFieldOffset + lengthFieldLength;表示长度域后第一个字节在整个包的偏移量
具体的拆包协议:
@Override
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List