具体实现
- DynamicLengthPacketHandler.java
public class DynamicLengthPacketHandler {private byte[] buffer = new byte[0];private int parseFlag = PARSE_FLAG_HEADER;public static final int HEADER_LENGTH = 4;private int bodyLength;private static final int PARSE_FLAG_HEADER = 0;private static final int PARSE_FLAG_BODY = 1;public List<byte[]> handleData(byte[] data) {byte[] newBuffer = new byte[buffer.length + data.length];System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);System.arraycopy(data, 0, newBuffer, buffer.length, data.length);buffer = newBuffer;List<byte[]> completeResults = new ArrayList<>();int position = 0;while (true) {if (parseFlag == PARSE_FLAG_HEADER) {if (buffer.length - position < HEADER_LENGTH) {break;}bodyLength = Byte.toUnsignedInt(buffer[position + 3]) |(Byte.toUnsignedInt(buffer[position + 2]) << 8) |(Byte.toUnsignedInt(buffer[position + 1]) << 16) |(Byte.toUnsignedInt(buffer[position]) << 24);position += HEADER_LENGTH;parseFlag = PARSE_FLAG_BODY;}if (position + bodyLength > buffer.length) {break;}byte[] completeResult = new byte[bodyLength];System.arraycopy(buffer, position, completeResult, 0, bodyLength);completeResults.add(completeResult);position += bodyLength;parseFlag = PARSE_FLAG_HEADER;}if (position > 0) {byte[] remaining = new byte[buffer.length - position];System.arraycopy(buffer, position, remaining, 0, remaining.length);buffer = remaining;}return completeResults;}public void clear() {buffer = new byte[0];parseFlag = PARSE_FLAG_HEADER;}public static byte[] buildPacket(String data) {byte[] body = data.getBytes();byte[] packet = new byte[4 + body.length];packet[0] = (byte) ((body.length >> 24) & 0xFF);packet[1] = (byte) ((body.length >> 16) & 0xFF);packet[2] = (byte) ((body.length >> 8) & 0xFF);packet[3] = (byte) (body.length & 0xFF);System.arraycopy(body, 0, packet, 4, body.length);return packet;}
}
测试用例
- 单个完整数据包
byte[] packet = DynamicLengthPacketHandler.buildPacket("Hello");DynamicLengthPacketHandler handler = new DynamicLengthPacketHandler();List<byte[]> results = handler.handleData(packet);System.out.println("解析结果数量: " + results.size());
for (byte[] result : results) {System.out.println("解析内容: " + new String(result));
}
# 输出结果解析结果数量: 1
解析内容: Hello
- 多个完整数据包(粘包)
byte[] packet1 = DynamicLengthPacketHandler. buildPacket("Hello");
byte[] packet2 = DynamicLengthPacketHandler. buildPacket("World");
byte[] packet3 = DynamicLengthPacketHandler. buildPacket("Java");byte[] combined = new byte[packet1.length + packet2.length + packet3.length];
System.arraycopy(packet1, 0, combined, 0, packet1.length);
System.arraycopy(packet2, 0, combined, packet1.length, packet2.length);
System.arraycopy(packet3, 0, combined, packet1.length + packet2.length, packet3.length);DynamicLengthPacketHandler handler = new DynamicLengthPacketHandler();List<byte[]> results = handler.handleData(combined);System.out.println("解析结果数量: " + results.size());
for (byte[] result : results) {System.out.println("解析内容: " + new String(result));
}
# 输出结果解析结果数量: 3
解析内容: Hello
解析内容: World
解析内容: Java
- 不完整数据包(半包)
byte[] fullPacket = DynamicLengthPacketHandler.buildPacket("HelloWorld");
byte[] partialData = new byte[8];
System.arraycopy(fullPacket, 0, partialData, 0, 8);DynamicLengthPacketHandler handler = new DynamicLengthPacketHandler();List<byte[]> results = handler.handleData(partialData);System.out.println("解析结果数量: " + results.size());
for (byte[] result : results) {System.out.println("解析内容: " + new String(result));
}
# 输出结果解析结果数量: 0
- 分包处理
byte[] fullPacket = DynamicLengthPacketHandler.buildPacket("HelloWorldJava");byte[] part1 = new byte[6];
byte[] part2 = new byte[5];
byte[] part3 = new byte[7];
System.arraycopy(fullPacket, 0, part1, 0, 6);
System.arraycopy(fullPacket, 6, part2, 0, 5);
System.arraycopy(fullPacket, 11, part3, 0, 7);DynamicLengthPacketHandler handler = new DynamicLengthPacketHandler();List<byte[]> results = handler.handleData(part1);System.out.println("第 1 次解析结果数量: " + results.size());
for (byte[] result : results) {System.out.println("解析内容: " + new String(result));
}results = handler.handleData(part2);System.out.println("第 2 次解析结果数量: " + results.size());
for (byte[] result : results) {System.out.println("解析内容: " + new String(result));
}results = handler.handleData(part3);System.out.println("第 3 次解析结果数量: " + results.size());
for (byte[] result : results) {System.out.println("解析内容: " + new String(result));
}
# 输出结果第 1 次解析结果数量: 0
第 2 次解析结果数量: 0
第 3 次解析结果数量: 1
解析内容: HelloWorldJava
- 空数据包
byte[] packet = DynamicLengthPacketHandler.buildPacket("");DynamicLengthPacketHandler handler = new DynamicLengthPacketHandler();List<byte[]> results = handler.handleData(packet);System.out.println("解析结果数量: " + results.size());
for (byte[] result : results) {System.out.println("解析内容: " + new String(result));
}
# 输出结果解析结果数量: 1
解析内容: