From a8a90fd2d5040e66cc66b3da122a7f82561ff6f6 Mon Sep 17 00:00:00 2001
From: 826220679@qq.com <826220679@qq.com>
Date: 星期六, 09 八月 2025 23:32:29 +0800
Subject: [PATCH] 优化了欢迎页面

---
 src/udptcp/PacketParser.java |  163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 163 insertions(+), 0 deletions(-)

diff --git a/src/udptcp/PacketParser.java b/src/udptcp/PacketParser.java
new file mode 100644
index 0000000..43f8429
--- /dev/null
+++ b/src/udptcp/PacketParser.java
@@ -0,0 +1,163 @@
+package udptcp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// 重命名为PacketParser,表示数据包解析器
+public class PacketParser {
+	// 添加十六进制字符数组常量
+    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+    // 缓冲区字节数组
+    private byte[] buffer = new byte[4096];
+    // 当前缓冲区有效数据长度
+    private int bufferLength = 0;
+
+    // 追加新数据到缓冲区
+    public void appendData(byte[] newData, int length) {
+        // 检查缓冲区是否足够
+        if (bufferLength + length > buffer.length) {
+            // 创建新的更大缓冲区
+            byte[] newBuffer = new byte[bufferLength + length];
+            // 复制原有数据
+            System.arraycopy(buffer, 0, newBuffer, 0, bufferLength);
+            buffer = newBuffer;
+        }
+        // 追加新数据
+        System.arraycopy(newData, 0, buffer, bufferLength, length);
+        // 更新缓冲区长度
+        bufferLength += length;
+    }
+    
+ // 新增方法:字节数组转十六进制字符串
+    public static String bytesToHexString(byte[] bytes) {
+        if (bytes == null) return "";
+        char[] hexChars = new char[bytes.length * 2];
+        for (int j = 0; j < bytes.length; j++) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
+            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
+        }
+        return new String(hexChars);
+    }
+
+    // 解析缓冲区中的所有完整数据包
+    public List<DataPacket> parsePackets() {
+        List<DataPacket> packets = new ArrayList<>();
+        int index = 0;  // 当前解析位置索引
+        
+        // 遍历缓冲区查找完整数据包
+        while (index <= bufferLength - 4) { // 确保有足够数据检查包头
+            // 检查包头标识 0x55 0xAA
+            if (buffer[index] == 0x55 && (buffer[index + 1] & 0xFF) == 0xAA) {
+                // 获取包类型(第3字节)
+                int packetType = buffer[index + 2] & 0xFF;
+                // 获取数据长度(第4字节)
+                int dataLenField = buffer[index + 3] & 0xFF;
+                // 计算完整包长度(包头+数据+校验)
+                int totalPacketLen = 4 + dataLenField + 2;  // 增加2字节校验位
+                
+                // 检查是否有足够数据构成完整包
+                if (index + totalPacketLen > bufferLength) {
+                    break; // 数据不足,等待更多数据
+                }
+                
+                // 提取完整数据包
+                byte[] packetData = new byte[totalPacketLen];
+                System.arraycopy(buffer, index, packetData, 0, totalPacketLen);
+                
+                // 验证校验和
+                if (verifyChecksum(packetData)) {
+                    // 解析单个数据包
+                    DataPacket packet = parseSinglePacket(packetType, packetData);
+                    if (packet != null) {
+                        packets.add(packet); // 添加到结果列表
+                    }
+                    index += totalPacketLen; // 移动到下一个包
+                } else {
+                    index++; // 校验失败,跳过当前字节
+                }
+            } else {
+                index++; // 非包头标识,继续查找
+            }
+        }
+        
+        // 清理已处理数据
+        if (index > 0) {
+            int remaining = bufferLength - index;
+            if (remaining > 0) {
+                // 移动剩余数据到缓冲区开头
+                System.arraycopy(buffer, index, buffer, 0, remaining);
+            }
+            bufferLength = remaining; // 更新缓冲区长度
+        }
+        
+        return packets;
+    }
+
+    // 校验数据包完整性
+    private boolean verifyChecksum(byte[] packet) {
+        int len = packet.length;
+        if (len < 4) return false; // 长度不足
+        
+        int sum = 0;
+        // 计算从第3字节到倒数第3字节的和(跳过包头和校验位)
+        for (int i = 2; i < len - 2; i++) {
+            sum += packet[i] & 0xFF;
+        }
+        // 取反得到16位校验和
+        sum = ~sum & 0xFFFF;
+        
+        // 提取包中的校验和(小端格式)
+        int receivedChecksum = ((packet[len - 1] & 0xFF) << 8) | (packet[len - 2] & 0xFF);
+        
+        // 比较校验和
+        return sum == receivedChecksum;
+    }
+
+    // 解析单个数据包
+    private DataPacket parseSinglePacket(int packetType, byte[] packet) {        
+        
+        // 创建数据包对象(包含包类型)
+        return new DataPacket(packetType, packet);
+    }
+
+    // 数据包内部类
+    public static class DataPacket {
+        private final int packetType;  // 包类型
+        private final byte[] packet;//包数据
+
+        public DataPacket(int packetType, byte[] packet) {
+            this.packetType = packetType;
+            this.packet = packet;
+        }
+        
+        // 获取包类型
+        public int getPacketType() {
+            return packetType;
+        }
+        
+        // 包数据
+        public byte[] getPacket() {
+            return packet;
+        }
+        
+    }
+
+    // HEX字符串转字节数组
+    public static byte[] hexStringToBytes(String hex) {
+        // 移除空格
+        hex = hex.replaceAll("\\s", "");
+        int len = hex.length();
+        // 创建结果数组
+        byte[] data = new byte[len / 2];
+        // 每两个字符转换一个字节
+        for (int i = 0; i < len; i += 2) {
+            // 高位转换
+            int high = Character.digit(hex.charAt(i), 16) << 4;
+            // 低位转换
+            int low = Character.digit(hex.charAt(i + 1), 16);
+            data[i / 2] = (byte) (high | low);
+        }
+        return data;
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.3