‘liusuyi’
2024-03-09 63bc9328ab5abb7e7233701bbcdce61b6caa99b7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.ard.utils.netty.tcp;
 
import com.ard.utils.util.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 MessageHandler {
    // 创建缓冲区列表
    private List<Byte> buffer = new ArrayList<>();
 
    /**
     * 接收完整包
     */
    public 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);
 
        //判断数据的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;
    }
}