当前位置: 首页 > news >正文

Java 开发 - 粘包处理器 - 基于消息头 + 消息体

具体实现

  • 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;}
}

测试用例

  1. 单个完整数据包
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
  1. 多个完整数据包(粘包)
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
  1. 不完整数据包(半包)
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
  1. 分包处理
byte[] fullPacket = DynamicLengthPacketHandler.buildPacket("HelloWorldJava");byte[] part1 = new byte[6]; // 头部 + 2 字节身体
byte[] part2 = new byte[5]; // 5 字节身体
byte[] part3 = new byte[7]; // 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
  1. 空数据包
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
解析内容: 
http://www.dtcms.com/a/604915.html

相关文章:

  • dify零基础入门示例
  • 跨语言智能再升级!Multi-LMentry 打造多语理解新基准;Nemotron-Personas-USA重塑虚拟人画像生成
  • 门户网站建设项目书免费拒绝收费网站
  • 研发管理知识库(13)阿里云的DevOps工具介绍
  • WPF 使用UserControl / ContentControl显示子界面
  • Docker 的底层工作原理
  • 互联网门户网站是什么意思网站建设 源美设计
  • 重庆商业网站有哪些产品网站建设方案
  • C基础学习过程02
  • 视频矩阵哪个品牌好 十大视频矩阵品牌
  • 电子书《21天学通Java(第5版)》
  • maven 私服上传jar
  • 从自动驾驶到智能辅导:人工智能如何重塑商业与生活
  • Hadess入门到精通 - 如何管理通用Generic制品
  • 万物互联时代,如何选择合适的时序数据库?
  • 集团门户网站建设做国外网站要注意什么
  • 软件设计模式-适配器模式
  • 软件工程(速成笔记)
  • 深圳苏州企业网站建设服务公司网站建设很难吗
  • sward实战教程系列(4) - 如何编写Markdown文档
  • 树莓派5-ubuntu 24.04 ros-jazzy-desktop 创建 robot_navigation 包
  • 【Linux】调试监听接口是否正常
  • Flink CDC + StarRocks用 StarRocks Connector 打通实时明细与分析
  • Linux《Socket编程Tcp》
  • 2025.11.13 力扣每日一题
  • “暗激子(dark excitons)” 以 30万倍亮度被观测到
  • 数据归一化:提升模型训练的关键技巧
  • 网站外链建设可以提升网站权重对吗三亚平台公司
  • 怎么做一种网站为别人宣传lamp 做网站
  • UE5制作扭曲声波效果