netty自定义解包器(注:应用层数据结构)

/**
 * 帧起始域	帧长度域	帧长度域取反	序列号域	数据对象	帧类型码	数据域	帧校验域 帧结束域
 * 数据结构   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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值