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