package com.ard.utils.tcp;
|
|
import com.ard.utils.ByteUtils;
|
|
import javax.xml.bind.DatatypeConverter;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
|
/**
|
* @Description: 报文解析
|
* @ClassName: MessageParsing
|
* @Author: 刘苏义
|
* @Date: 2023年07月03日15:30
|
* @Version: 1.0
|
**/
|
public class MessageParsing {
|
// 创建缓冲区列表
|
private static List<Byte> buffer = new ArrayList<>();
|
|
/**
|
* 接收完整包
|
*/
|
public static byte[] receiveCompletePacket(byte[] receivedData) {
|
// 定义包尾字节序列
|
byte[] packetEnd = {0x01, 0x02, 0x00};
|
// 添加已接收的数据到缓冲区
|
for (byte data : receivedData) {
|
buffer.add(data);
|
}
|
// 检查缓冲区中的数据是否包含完整的包
|
while (buffer.size() >= packetEnd.length) {
|
int endIndex = findPacketEndIndex(buffer, packetEnd);
|
if (endIndex != -1) {
|
// 找到完整的包
|
byte[] packet = extractPacketFromBuffer(buffer, endIndex + packetEnd.length);
|
return packet;
|
} else {
|
// 未找到包尾,继续接收数据
|
break;
|
}
|
}
|
|
// 未找到完整的包
|
return null;
|
}
|
|
/**
|
* crc32校验检查
|
* 刘苏义
|
* 2023/7/4 11:24
|
*/
|
public static Boolean CRC32Check(byte[] packet) {
|
//System.out.println(DatatypeConverter.printHexBinary(packet));
|
int headerLength = 3;//包头3个字节
|
int footerLength = 3;//包尾3个字节
|
int crcLength = 4;//crc校验4个字节
|
//去掉包头包尾
|
byte[] payloadCrc32 = ByteUtils.removeHeaderAndFooter(packet, headerLength, footerLength);
|
//System.out.println(DatatypeConverter.printHexBinary(payloadCrc32));
|
//获取到数据携带的crc32值
|
byte[] oldCrc32 = ByteUtils.getLastBytes(payloadCrc32, crcLength);
|
//去掉包头包尾crc32字节,仅保留负载
|
byte[] payload = ByteUtils.removeHeaderFooterAndCRC(packet, headerLength, footerLength, crcLength);
|
// System.out.println(DatatypeConverter.printHexBinary(payload));
|
//计算负载的crc32值
|
byte[] NewCrc32 = ByteUtils.parseCrc32(payload);
|
System.out.println("old:"+DatatypeConverter.printHexBinary(oldCrc32));
|
System.out.println("new:"+DatatypeConverter.printHexBinary(NewCrc32));
|
//判断数据的crc32校验值和计算值是否相同
|
if (Arrays.equals(oldCrc32, NewCrc32)) {
|
return true;
|
} else {
|
return false;
|
}
|
}
|
|
/**
|
* 获取包结束索引
|
*/
|
public static int findPacketEndIndex(List<Byte> buffer, byte[] packetEnd) {
|
for (int i = 0; i <= buffer.size() - packetEnd.length; i++) {
|
boolean isMatch = true;
|
for (int j = 0; j < packetEnd.length; j++) {
|
if (buffer.get(i + j) != packetEnd[j]) {
|
isMatch = false;
|
break;
|
}
|
}
|
if (isMatch) {
|
return i;
|
}
|
}
|
return -1;
|
}
|
|
/**
|
* 从缓冲区提取数据包
|
*/
|
public static byte[] extractPacketFromBuffer(List<Byte> buffer, int endIndex) {
|
byte[] packet = new byte[endIndex];
|
for (int i = 0; i < endIndex; i++) {
|
packet[i] = buffer.get(i);
|
}
|
buffer.subList(0, endIndex).clear();
|
return packet;
|
}
|
|
/**
|
* 去掉包头和包尾校验及转义
|
*/
|
public static byte[] transferData(byte[] data) {
|
int headerLength = 3;//包头3个字节
|
int footerLength = 3;//包尾3个字节
|
int crcLength = 4;//crc校验4个字节
|
data= ByteUtils.removeHeaderFooterAndCRC(data,headerLength,footerLength,crcLength);
|
String dataStr = DatatypeConverter.printHexBinary(data);
|
if (dataStr.contains("01020201")) {//转义01020201
|
dataStr = dataStr.replaceAll("01020201", "010201");
|
}
|
if (dataStr.contains("01020200")) {//转义01020200
|
dataStr = dataStr.replaceAll("01020200", "010200");
|
}
|
if (dataStr.contains("01020202")) {//转义01020202
|
dataStr = dataStr.replaceAll("01020202", "010202");
|
}
|
data = DatatypeConverter.parseHexBinary(dataStr);
|
return data;
|
}
|
}
|