具体实现
- 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
解析内容: