ModbusDecoderNetty,crc16modbus
/** * *ModbusDecoderNetty * */ @Slf4j public class ModbusDecoderNetty extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { int iReadableBytes = in.readableBytes(); if (iReadableBytes > 0) { int iReaderIndex = in.readerIndex(); //判断是否已登录 Session session = ChannelMap.getInstance().getClientInstance(ctx.channel()); if (session == null || !session.hasAuth()) { //设备未登录。不做解析。直接返还 if (in.getByte(in.readerIndex())==0){ //注册包 if(iReadableBytes < 16){ // 数据包未收齐 return; } ByteBuf bbPacket = Unpooled.buffer(16); in.getBytes(iReaderIndex, bbPacket, 16); out.add(bbPacket); in.readerIndex(16 + iReaderIndex); in.markReaderIndex(); log.info("[NettyServerPacketDecoder]注册解析成功"); return; }else { log.error("[NettyServerPacketDecoder]注册解析失败"); in.readerIndex(iReadableBytes + iReaderIndex); in.markReaderIndex(); return; } }else{ int iStartFlag0 = NettyUtil.byte2Int(in.getByte(0 + iReaderIndex)); int iStartFlag1 = NettyUtil.byte2Int(in.getByte(1 + iReaderIndex)); if (iStartFlag0 == 0xFE || iStartFlag0 == 0xFF ){ //心跳包 ByteBuf bbPacket = Unpooled.buffer(1); in.getBytes(iReaderIndex, bbPacket, 1); out.add(bbPacket); in.readerIndex(1 + iReaderIndex); in.markReaderIndex(); return; } else { // modbus if (iReadableBytes < 5) { // 数据包未收齐 return; } for(int i = 1 + iReaderIndex ; i < iReadableBytes; i++){ int iStartFlag0_temp = NettyUtil.byte2Int(in.getByte(i - 1)); int iStartFlag1_temp = NettyUtil.byte2Int(in.getByte(i )); if (iStartFlag1_temp == 0x03) { iReaderIndex = i -1; iStartFlag0 = iStartFlag0_temp; iStartFlag1 = iStartFlag1_temp; break; } } if(iStartFlag1 == 0x03){ // 确定报文长度,从索引11开始取2个字节低12位 int iFlagLen = in.getByte(2 + iReaderIndex); int iPayloadLen = iFlagLen & 0x0FFF; int iPacketLen = 5 + iPayloadLen; if (iPacketLen <= iReadableBytes) { if(iPacketLen >= 120 || iStartFlag0 > 32){ in.readerIndex(1 + iReaderIndex); in.markReaderIndex(); return; }else{ // 有完整的数据包 ByteBuf bbPacket = Unpooled.buffer(iPacketLen); in.getBytes(iReaderIndex, bbPacket, iPacketLen); out.add(bbPacket); in.readerIndex(iPacketLen + iReaderIndex); in.markReaderIndex(); } } else { // 非完整的数据包 in.resetReaderIndex(); } return; } return; } } } } }
public static int crc16(byte[] data) { int crc = 65535; // int pol = 'ꀁ'; int pol = 40961; System.out.println("pol:" + pol); for(int i = 0; i < data.length; ++i) { crc ^= data[i] & 255; for(int j = 0; j < 8; ++j) { if ((crc & 1) != 0) { crc >>= 1; crc ^= pol; } else { crc >>= 1; } } } crc = (crc & '\uff00') >> 8 | (crc & 255) << 8; return crc; }
public static boolean hasValidCRC16MODBUS(byte[] buffer) { if (buffer.length < 3) { return false; } else { byte[] data = new byte[buffer.length - 2]; System.arraycopy(buffer, 0, data, 0, data.length); int source = BytesUtils.beToInt(buffer, buffer.length - 2, 2); int target = crc16(data); return source == target; } }
posted on 2025-08-15 10:13 yebinghuai-qq-com 阅读(8) 评论(0) 收藏 举报
浙公网安备 33010602011771号