更新消息回复\校验码生成

main
小鱼干 4 weeks ago
parent 54a4c84eb8
commit d6d31aee87

@ -94,5 +94,8 @@ public class BeeHive implements Serializable {
* *
*/ */
private LocalDateTime dateUploadTime; private LocalDateTime dateUploadTime;
/**
*
*/
private String dateUploadTimeHex;
} }

@ -116,6 +116,7 @@ public class HandlerDateProcessing {
// return null; // return null;
// } // }
beeHive.setDateUploadTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(date), ZoneId.systemDefault())); beeHive.setDateUploadTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(date), ZoneId.systemDefault()));
beeHive.setDateUploadTimeHex(getSubData(data, startIndex, endIndex));
break; break;
case 2: case 2:
//当前温度值2 //当前温度值2

@ -12,6 +12,7 @@ import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
@ -20,6 +21,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.*; import java.util.concurrent.*;
import static com.hive.communication.util.CheckCode.*;
import static com.hive.util.DateConvetUtil.getCurrentSeconds; import static com.hive.util.DateConvetUtil.getCurrentSeconds;
@Slf4j @Slf4j
@ -43,33 +45,55 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
* *
*/ */
public static void sendActive(ChannelHandlerContext ctx, boolean flag, BeeHive beeHive, boolean notice) { public static void sendActive(ChannelHandlerContext ctx, boolean flag, BeeHive beeHive, boolean notice) {
if (flag) { if (flag) {
try { try {
// String paddedString = String.format("%4s", code).replace(' ', '0'); String start="99";
String codes = "注册完回复"; String end ="AA";
//获取十分钟后的时间秒数需要转换为16进制 StringBuilder stringBuilder = new StringBuilder();
getCurrentSeconds(); stringBuilder.append(start);
log.info("当前时间: {}, 消息: {}", LocalDateTime.now(), codes); stringBuilder.append("8561");
// 先将十六进制字符串转换为字节数组 stringBuilder.append(beeHive.getDateUploadTimeHex());
byte[] messageBytes = HexConversion.hexStringToByteArray(codes); stringBuilder.append("0b01");
// 将字节数组封装到ByteBuf中 // String paddedString = String.format("%4s", code).replace(' ', '0');
ByteBuf messageBuffer = Unpooled.wrappedBuffer(messageBytes); //获取十分钟后的时间秒数,
// 通过ChannelHandlerContext发送ByteBuf // 转换为16进制
// 关联设备编号与Channel String hexSeconds = Long.toHexString(getCurrentSeconds()).toUpperCase();
// sendRequest(ctx.channel(),messageBuffer,devicePointsSensor.getId()); stringBuilder.append(hexSeconds);
retrySend(ctx, messageBuffer) stringBuilder.append("0000ff000000");
.whenComplete((result,error) -> {
log.info("发送状态: {},当前时间: {}, 消息: {},名称:{}蜂箱id{}", result,LocalDateTime.now(), codes,beeHive.getBeeHiveName(),beeHive.getId()); byte[] dataSum = hexStringToByteArray(stringBuilder.toString());
// 计算校验码1
byte checksum1 = calculateChecksum1(dataSum);
// 计算校验码2
byte checksum2 = calculateChecksum2(dataSum);
String checksum1Hex = String.format("%02X", checksum1);
String checksum2Hex = String.format("%02X", checksum2);
stringBuilder.append(checksum1Hex);
stringBuilder.append(checksum2Hex);
stringBuilder.append(end);
log.info("当前时间: {}, 消息: {}", LocalDateTime.now(), stringBuilder);
// 先将十六进制字符串转换为字节数组
byte[] messageBytes = HexConversion.hexStringToByteArray(stringBuilder.toString());
// 将字节数组封装到ByteBuf中
ByteBuf messageBuffer = Unpooled.wrappedBuffer(messageBytes);
// 通过ChannelHandlerContext发送ByteBuf
// 关联设备编号与Channel
// sendRequest(ctx.channel(),messageBuffer,devicePointsSensor.getId());
retrySend(ctx, messageBuffer)
.whenComplete((result, error) -> {
log.info("发送状态: {},当前时间: {}, 消息: {},名称:{}蜂箱id{}", result, LocalDateTime.now(), stringBuilder, beeHive.getBeeHiveName(), beeHive.getId());
/* if (result) { /* if (result) {
// 发送成功 // 发送成功
} else { } else {
// 发送失败 // 发送失败
}*/ }*/
}); });
} catch (Exception e) { } catch (Exception e) {
// 处理异常 // 处理异常
} }
} }
} }
@ -92,6 +116,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
} }
return future; return future;
} }
/** /**
* *
*/ */
@ -99,31 +124,32 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
messageBuffer.retain(); // 增加引用计数 messageBuffer.retain(); // 增加引用计数
ChannelFuture sendFuture = ctx.writeAndFlush(messageBuffer); ChannelFuture sendFuture = ctx.writeAndFlush(messageBuffer);
sendFuture.addListener((ChannelFutureListener) sendFutureListener -> { sendFuture.addListener((ChannelFutureListener) sendFutureListener -> {
if (sendFutureListener.isSuccess()) { if (sendFutureListener.isSuccess()) {
messageBuffer.release(); // 释放在发送前增加的引用计数 messageBuffer.release(); // 释放在发送前增加的引用计数
future.complete(true); // 发送成功,将结果设置为 true future.complete(true); // 发送成功,将结果设置为 true
} else { } else {
if (remainingRetries > 0) { if (remainingRetries > 0) {
ctx.executor().schedule(() -> { ctx.executor().schedule(() -> {
// 发送失败,但还有剩余重试次数 // 发送失败,但还有剩余重试次数
if (messageBuffer.isReadable()) { if (messageBuffer.isReadable()) {
// 如果messageBuffer仍然可读重新使用它进行重试 // 如果messageBuffer仍然可读重新使用它进行重试
retrySendAsync(ctx,messageBuffer, remainingRetries - 1, future); retrySendAsync(ctx, messageBuffer, remainingRetries - 1, future);
} else { } else {
// messageBuffer不可读需要重新创建或复制一个新的messageBuffer // messageBuffer不可读需要重新创建或复制一个新的messageBuffer
ByteBuf newMessageBuffer = messageBuffer.retainedDuplicate(); ByteBuf newMessageBuffer = messageBuffer.retainedDuplicate();
retrySendAsync(ctx, newMessageBuffer, remainingRetries - 1, future); retrySendAsync(ctx, newMessageBuffer, remainingRetries - 1, future);
} }
}, 2, TimeUnit.SECONDS); }, 2, TimeUnit.SECONDS);
} else { } else {
messageBuffer.release(); // 释放在发送前增加的引用计数 messageBuffer.release(); // 释放在发送前增加的引用计数
future.complete(false); // 达到最大重试次数,将结果设置为 false future.complete(false); // 达到最大重试次数,将结果设置为 false
}
} }
}
}); });
} }
/** /**
* pendingRequests * pendingRequests
*/ */
@ -142,6 +168,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
return promise; return promise;
} }
/** /**
* *
*/ */
@ -179,7 +206,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
return null; return null;
} }
} }
/*****************************************处理收到的消息 *****************************************/ /*****************************************处理收到的消息 *****************************************/
/** /**
* *
@ -200,7 +227,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
// System.out.println("接收到的数据sb" + sb.toString()); // System.out.println("接收到的数据sb" + sb.toString());
// 检查消息是否是心跳请求 // 检查消息是否是心跳请求
if (sb.toString().equalsIgnoreCase(HEARTBEAT_REQUEST)) { if (sb.toString().equalsIgnoreCase(HEARTBEAT_REQUEST)) {
handleHeartbeat(ctx,msg); handleHeartbeat(ctx, msg);
} else { } else {
// 如果不是心跳请求调用ChannelInboundHandler的下一个处理器 // 如果不是心跳请求调用ChannelInboundHandler的下一个处理器
ctx.fireChannelRead(msg); ctx.fireChannelRead(msg);
@ -214,7 +241,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
private void handleHeartbeat(ChannelHandlerContext ctx, Object msg) { private void handleHeartbeat(ChannelHandlerContext ctx, Object msg) {
isHeartbeatReceived = true; isHeartbeatReceived = true;
ctx.fireChannelRead(msg); ctx.fireChannelRead(msg);
//ctx.fireChannelReadComplete(); //ctx.fireChannelReadComplete();
// 如果需要,发送心跳响应 // 如果需要,发送心跳响应
// ctx.writeAndFlush("FE"); // ctx.writeAndFlush("FE");

@ -1,35 +1,36 @@
package com.hive.communication.util; package com.hive.communication.util;
public class CheckCode { public class CheckCode {
// 计算字符串的校验码(异位校验)
public static int calculateParity(String input, boolean oddParity) { // 计算校验码1按位异或操作
int parity = 0; public static byte calculateChecksum1(byte[] data) {
for (char ch : input.toCharArray()) { byte checksum = 0x00;
parity ^= ch; for (byte b : data) {
} checksum ^= b;
// 根据需要调整奇偶校验位
int parityBit = Integer.bitCount(parity) % 2;
if (oddParity) {
parityBit = parityBit == 0 ? 1 : 0; // 奇校验如果0变成1如果1变成0
} }
return parityBit; return checksum;
} }
// 计算16进制字符串的校验码
public static int calculateChecksum(String hexString) {
int sum = 0;
// 每两个字符作为一个16进制数进行解析 // 计算校验码2加法操作
for (int i = 0; i < hexString.length(); i += 2) { public static byte calculateChecksum2(byte[] data) {
String hexPair = hexString.substring(i, i + 2); int sum = 0;
int hexValue = Integer.parseInt(hexPair, 16); for (byte b : data) {
sum += hexValue; sum += b & 0xFF; // & 0xFF 保证每个 byte 被当作无符号处理
} }
return (byte) (sum & 0xFF); // 取最后8位
// 保留最后8位
int checksum = sum & 0xFF; // 0xFF表示8位全1的掩码
return checksum;
} }
// 将十六进制字符串转换为字节数组
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
} }

Loading…
Cancel
Save