diff --git a/src/main/java/com/muyu/common/Config.java b/src/main/java/com/muyu/common/Config.java index af9cfe6..e700325 100644 --- a/src/main/java/com/muyu/common/Config.java +++ b/src/main/java/com/muyu/common/Config.java @@ -33,6 +33,16 @@ public class Config { */ public static boolean IS_CONNECT = false; + /** + * 报文起始位 + */ + public static final String MSG_START = "7E "; + + /** + * 报文结束位 + */ + public static final String MSG_END = "7E"; + /** * 连接消息VIN */ diff --git a/src/main/java/com/muyu/netty/operate/NettyClientMsg.java b/src/main/java/com/muyu/netty/operate/NettyClientMsg.java index ee4e500..6b32952 100644 --- a/src/main/java/com/muyu/netty/operate/NettyClientMsg.java +++ b/src/main/java/com/muyu/netty/operate/NettyClientMsg.java @@ -2,6 +2,7 @@ package com.muyu.netty.operate; import com.muyu.common.Config; +import com.muyu.utils.CalculateCheckDigit; import com.muyu.utils.ConversionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,8 +23,20 @@ public class NettyClientMsg { * @param msg */ public static void sendMsg(String msg){ - log.info("客户端发送消息:{}",msg); - Config.ctx.writeAndFlush(ConversionUtil.strToSixteen(msg) + Config.DATA_PACK_SEPARATOR); + log.info("发送消息:{}",msg); + //得到16进制报文 + String sHex = ConversionUtil.strToSixteen(msg); + //计算校验和 + String makeCheck = CalculateCheckDigit.makeCheck(sHex); + //拼接报文 - 起始位 + StringBuilder sb = new StringBuilder(Config.MSG_START); + //拼接报文 - 数据位 + sb.append(sHex); + //拼接报文 - 校验位 + sb.append(makeCheck).append(" "); + //拼接报文 截止位 + sb.append(Config.MSG_END); + Config.ctx.writeAndFlush(sb.toString() + Config.DATA_PACK_SEPARATOR); } /** diff --git a/src/main/java/com/muyu/utils/CalculateCheckDigit.java b/src/main/java/com/muyu/utils/CalculateCheckDigit.java new file mode 100644 index 0000000..dce7f70 --- /dev/null +++ b/src/main/java/com/muyu/utils/CalculateCheckDigit.java @@ -0,0 +1,58 @@ +package com.muyu.utils; + +/** + * 校验位计算 + */ +public class CalculateCheckDigit { + + /** + * 输入十六进制,输出两位校验位 + * */ + public static void main(String args[]) { + // 输入十六进制 + String sHex = "01 F1 00 04 03 06 01 B0"; + // 去掉中间空格 + sHex = sHex.replace(" ", ""); + // 计算并获取校验位 + String result = makeCheckSum(sHex); + // 输出两位校验位 结果是B0 + System.out.println(result); + } + + /** + * 不去空格 + * @param sHex + * @return + */ + public static String makeCheck(String sHex){ + return makeCheckSum(sHex.replace(" ", "")); + } + + /** + * 计算校验位 ,返回十六进制校验位 + * */ + private static String makeCheckSum(String data) { + int dSum = 0; + int length = data.length(); + int index = 0; + // 遍历十六进制,并计算总和 + while (index < length) { + // 截取2位字符 + String s = data.substring(index, index + 2); + // 十六进制转成十进制 , 并计算十进制的总和 + dSum += Integer.parseInt(s, 16); + index = index + 2; + } + + // 用256取余,十六进制最大是FF,FF的十进制是255 + int mod = dSum % 256; + // 余数转成十六进制 + String checkSumHex = Integer.toHexString(mod); + length = checkSumHex.length(); + if (length < 2) { + // 校验位不足两位的,在前面补0 + checkSumHex = "0" + checkSumHex; + } + return checkSumHex; + } +}