先定义
public int recurCount = 0; // 数据包重发次数计数器(仅用于内部处理,非业务数据)
public IPEndPoint endPoint; // 目标终端的IP地址和端口号
// 数据包头部信息
public int protoSize; // 业务数据的字节大小
public int session; // 会话ID,用于标识客户端连接
public int sn; // 序列号,用于消息排序和去重
public int moduleID; // 模块ID,标识消息所属的功能模块
public long time; // 发送时间戳
public int messageType; // 消息类型(0:ACK确认包 1:业务消息包)
public int messageID; // 消息ID,标识具体的协议号
// 数据部分
public byte[] proto; // 业务数据的字节数组(protobuf序列化后的数据)
public byte[] buffer; // 完整的数据包字节数组(包含头部信息和业务数据)
构建请求报文
public BufferEntity(
IPEndPoint endPoint,
int session,
int sn,
int moduleID,
int messageType,
int messageID,
byte[] proto
)
{
protoSize = proto.Length; // 记录业务数据的大小
this.endPoint = endPoint;
this.session = session;
this.sn = sn;
this.moduleID = moduleID;
this.messageType = messageType;
this.messageID = messageID;
this.proto = proto;
}
编码接口,序列化
public byte[] Encoder(bool isAck)
{
// 创建固定大小的字节数组(头部32字节 + 业务数据大小)
byte[] data = new byte[32 + protoSize];
if (isAck == true)
{
protoSize = 0; // ACK包没有业务数据
}
// 将各字段转换为字节数组
byte[] _length = BitConverter.GetBytes(protoSize);
byte[] _session = BitConverter.GetBytes(session);
byte[] _sn = BitConverter.GetBytes(sn);
byte[] _moduleid = BitConverter.GetBytes(moduleID);
byte[] _time = BitConverter.GetBytes(time);
byte[] _messageType = BitConverter.GetBytes(messageType);
byte[] _messageID = BitConverter.GetBytes(messageID);
// 按照协议格式组装数据包
Array.Copy(_length, 0, data, 0, 4); // 0-3字节: 业务数据长度
Array.Copy(_session, 0, data, 4, 4); // 4-7字节: 会话ID
Array.Copy(_sn, 0, data, 8, 4); // 8-11字节: 序列号
Array.Copy(_moduleid, 0, data, 12, 4); // 12-15字节: 模块ID
Array.Copy(_time, 0, data, 16, 8); // 16-23字节: 时间戳
Array.Copy(_messageType, 0, data, 24, 4); // 24-27字节: 消息类型
Array.Copy(_messageID, 0, data, 28, 4); // 28-31字节: 消息ID
// 如果不是ACK包,追加业务数据
if (!isAck)
{
Array.Copy(proto, 0, data, 32, proto.Length); // 32字节之后: 业务数据
}
buffer = data;
return data;
}
反序列
private void DeCode()
{
// 检查数据包是否至少包含长度字段(4字节)
if (buffer.Length >= 4)
{
protoSize = BitConverter.ToInt32(buffer, 0); // 解析业务数据长度
// 检查数据包是否完整(头部32字节 + 业务数据长度)
if (buffer.Length == protoSize + 32)
{
isFull = true;
}
}
else
{
isFull = false;
return;
}
// 解析头部各字段
session = BitConverter.ToInt32(buffer, 4); // 会话ID
sn = BitConverter.ToInt32(buffer, 8); // 序列号
moduleID = BitConverter.ToInt32(buffer, 12); // 模块ID
time = BitConverter.ToInt64(buffer, 16); // 时间戳
messageType = BitConverter.ToInt32(buffer, 24); // 消息类型
messageID = BitConverter.ToInt32(buffer, 28); // 消息ID
// 如果不是ACK包,解析业务数据
if (messageType != 0)
{
proto = new byte[protoSize];
Array.Copy(buffer, 32, proto, 0, protoSize); // 复制业务数据
}
}
标签:字节,int,LOL,buffer,BitConverter,byte,public
From: https://www.cnblogs.com/dou66/p/18641450