package com.hb.proj.gather.test; import java.util.Arrays; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.hb.proj.gather.protocol.ChannelGroupMgr; import com.hb.proj.gather.protocol.GatherRespParser; import com.hb.proj.gather.utils.ByteUtils; import com.hb.proj.gather.utils.Crc16Utils; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class GatherProtocolHandler extends ChannelInboundHandlerAdapter { private final static Logger logger = LoggerFactory.getLogger(GatherProtocolHandler.class); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //msg:如果设置了decoder编码器,则msg为编码后的类型,可强制转换 byte[] recmsg=(byte[])msg; String hexmsg=ByteUtils.toHexString(recmsg); //两字节且不以0103开头,就认为是心跳数据-作为设备号,该方法并不可靠,有可能把采集的残包数据当作心跳 if(recmsg.length==2&&(!hexmsg.startsWith("0103"))) { if(!ChannelGroupMgr.contains(ctx.channel())) { ChannelGroupMgr.add(ctx.channel(),ByteUtils.toIntStr(recmsg)); } } else if(hexmsg.startsWith("0103")){ //采集指令返回数据 int datalen=recmsg[2]&0xff; //数据区字节数 logger.info("数据字节长度:{}",datalen); byte[] hdBodyMsg=Arrays.copyOfRange(recmsg,0,datalen+3); //除CRC外的消息主体 byte[] crc16=Arrays.copyOfRange(recmsg,datalen+3,datalen+3+2); //2字节校验位 //System.arraycopy(recmsg,0,hdBodyMsg,0,hdBodyMsg.length); //System.arraycopy(recmsg,hdBodyMsg.length,crc16,0,crc16.length); int calCrc16=Crc16Utils.getCRC(hdBodyMsg); logger.info("接收CRC:{}:{},计算CRC:{}",ByteUtils.toHexString(crc16),ByteUtils.byte2ToIntHL(crc16),calCrc16); if(ByteUtils.byte2ToIntHL(crc16)==calCrc16) { //crc校验通过 //List smpdatas=GatherRespParser.parseFloat(Arrays.copyOfRange(hdBodyMsg,3,datalen+3), 4); //logger.info("解析后的采集数据{}",smpdatas); } } ctx.fireChannelRead(msg); } }