/**
* 帧起始域 帧长度域 帧长度域取反 序列号域 数据对象 帧类型码 数据域 帧校验域 帧结束域
* 数据结构 2字节 2字节 2字节 1字节 1字节 1字节 N字节 2字节 1字节
* 帧长度域:从序列号域到帐校验域的所有字节数
*/
@Slf4j
public class CustomUnpackUtils extends ByteToMessageDecoder {
private static final int FRAME_START_FIELD_LENGTH = 2;//帧起始域
private static final int FRAME_LENGTH_FIELD_LENGTH = 2;//帧长度域
private static final int FRAME_LENGTH_FIELD_NEGATION_LENGTH = 2;//帧长度域取反
private static final int FINISH = 1;//帧结束域
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
//bytebuf gc出错怎么解决
log.info("收到报文");
if (in == null) {
log.info("收到的报文为空");
return;
}
in.markReaderIndex();
log.info("长度-->" + in.readableBytes());
// 读取帧起始域
byte[] frameStartBytes = new byte[FRAME_START_FIELD_LENGTH];
in.getBytes(0, frameStartBytes);
String fheadStr = Hex.encodeHexString(frameStartBytes);
if (!fheadStr.toUpperCase().equals("55AA")) {
in.clear();
return;
}
// 读取帧长度域
byte[] frameLengthBytes = new byte[FRAME_LENGTH_FIELD_LENGTH];
in.getBytes(2, frameLengthBytes);//从2个字节读取数据长度
int frameLength = byteArrayToInt(frameLengthBytes);
log.info("收到的数据长度---->" + frameLength);
// 检查帧长度是否合法
if (frameLength < 0) {
throw new TooLongFrameException("Frame length is invalid: " + frameLength);
}
// 等待接收完整的帧
if (in.readableBytes() < (frameLength + FRAME_START_FIELD_LENGTH + FRAME_LENGTH_FIELD_LENGTH + FRAME_LENGTH_FIELD_NEGATION_LENGTH + FINISH)) {
in.resetReaderIndex();
return;
}
// 读取完整的帧数据
ByteBuf frameData = in.readBytes(frameLength + FRAME_START_FIELD_LENGTH + FRAME_LENGTH_FIELD_LENGTH + FRAME_LENGTH_FIELD_NEGATION_LENGTH + FINISH);
// 丢弃已读取的字节
in.discardReadBytes();
// 添加帧数据到输出列表
out.add(frameData);
//最后做gc处理
/* System.gc();*/
}
public static int byteArrayToInt(byte[] byteArray) {
int value = 0;
for (int i = 0; i < byteArray.length; i++) {
value = (value << 8) | (byteArray[i] & 0xFF);
}
return value;
}
}
netty自定义解包器(注:应用层数据结构)
最新推荐文章于 2024-06-14 09:35:50 发布