在使用netty做交互时会出现,一条消息被拆分成多条报文,也存在一条报文包含了多条消息,这就是netty的拆包与粘包。
对于netty的粘包与拆包,当前最常见的处理方式一般为,使用消息头以及消息体长度进行处理
例如我们报文格式如下
消息头 | 消息体长度 | 加密标识(可选) | 加密类型(可选) | 消息体标识 | 消息体 | 校验码 |
---|---|---|---|---|---|---|
4字节 | 4字节 | 1字节(本文不包含) | 1字节(本文不包含) | 4字节 | N字节 | 2字节(本文不包含) |
下面使用一段代码表示如何处理拆包粘包,代码仅供参考,具体需要按照实际业务来处理
public class NettyDecoder extends ByteToMessageDecoder {
public final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
//判断长度信息是否满足最低请求头字节数
if (in.readableBytes() >= 4) {
//获取前消息体长度
short dataLength = in.readShort();
if (dataLength < 0) {
return;
}
//消息体长度大于实际剩余长度,说明剩余消息不够,出现了拆包那我们就等后边数据来了我们在处理
if (in.readableBytes() < dataLength) {
//重置读取位置
in.resetReaderIndex();
} else {
//在剩余字节中取出消息体长度的信息,预防粘包情况
ByteBuf buffer = Unpooled.buffer(dataLength);
in.readBytes(buffer);
//由后边的处理器进行处理
out.add(buffer);
}
}
}
}