hlp:荆州版本
This commit is contained in:
+186
-186
@@ -1,186 +1,186 @@
|
||||
#include "message.h"
|
||||
|
||||
Message::Message(QObject *parent)
|
||||
{
|
||||
FRAME_START = 0x2B; // '+'
|
||||
FRAME_END = 0x3C; // '<'
|
||||
HEADER_SIZE = 4; // 1(起始) + 2(长度) + 1(预留)
|
||||
TRAILER_SIZE = 1; // 1(结束)
|
||||
MIN_FRAME_SIZE = HEADER_SIZE + TRAILER_SIZE; // 5字节
|
||||
}
|
||||
|
||||
Message::~Message()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QByteArray Message::pack(const QByteArray &data)
|
||||
{
|
||||
// 检查数据长度
|
||||
if (data.size() > 65535) {
|
||||
//Message::pack - 数据长度超过65535字节限制
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
// 创建协议头
|
||||
MsgHead head;
|
||||
head.start = FRAME_START;
|
||||
head.reserved = 0;
|
||||
// 只保存实际内容的长度
|
||||
head.length = static_cast<quint16>(data.size());
|
||||
// head.toNetworkOrder(); // 转换为大端序
|
||||
|
||||
// 创建协议尾
|
||||
MsgTail tail;
|
||||
tail.end = FRAME_END;
|
||||
|
||||
// 构建完整帧
|
||||
QByteArray frame;
|
||||
frame.reserve(HEADER_SIZE + data.size() + TRAILER_SIZE);
|
||||
|
||||
// 添加头部
|
||||
frame.append(reinterpret_cast<const char*>(&head), HEADER_SIZE);
|
||||
|
||||
// 添加数据
|
||||
if (!data.isEmpty()) {
|
||||
frame.append(data);
|
||||
}
|
||||
|
||||
// 添加尾部
|
||||
frame.append(reinterpret_cast<const char*>(&tail), TRAILER_SIZE);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
bool Message::unpack(const QByteArray &frame, QByteArray &data)
|
||||
{
|
||||
if (!validate(frame)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查数据长度
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
|
||||
quint16 dataLength = head.length;
|
||||
int expectedSize = HEADER_SIZE + dataLength + TRAILER_SIZE;
|
||||
|
||||
if (frame.size() < expectedSize) {
|
||||
// 帧不完整
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取数据
|
||||
data = frame.mid(HEADER_SIZE, dataLength);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Message::validate(const QByteArray &frame)
|
||||
{
|
||||
// 检查最小长度
|
||||
if (frame.size() < MIN_FRAME_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 读取头部
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
|
||||
// 验证起始标识
|
||||
if (!head.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
quint16 dataLength = head.length;
|
||||
|
||||
// 读取尾部
|
||||
MsgTail tail;
|
||||
memcpy(&tail, frame.constData() + HEADER_SIZE + dataLength, TRAILER_SIZE);
|
||||
|
||||
// 验证结束标识
|
||||
if (!tail.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QByteArray Message::extractFrame(const QByteArray &buffer, int &consumedBytes)
|
||||
{
|
||||
consumedBytes = 0;
|
||||
|
||||
// 查找起始标识
|
||||
int startPos = buffer.indexOf(FRAME_START);
|
||||
if (startPos < 0) {
|
||||
return QByteArray(); // 没有找到起始标识
|
||||
}
|
||||
|
||||
// 检查是否有完整的头部
|
||||
if (startPos + HEADER_SIZE > buffer.size()) {
|
||||
return QByteArray(); // 头部不完整
|
||||
}
|
||||
|
||||
// 读取数据长度
|
||||
quint16 dataLength = readLength(buffer.mid(startPos, HEADER_SIZE));
|
||||
|
||||
// 计算完整帧大小
|
||||
int frameSize = HEADER_SIZE + dataLength + TRAILER_SIZE;
|
||||
|
||||
// 检查是否有完整的帧
|
||||
if (startPos + frameSize > buffer.size()) {
|
||||
return QByteArray(); // 帧不完整
|
||||
}
|
||||
|
||||
// 提取并验证完整帧
|
||||
QByteArray frame = buffer.mid(startPos, frameSize);
|
||||
|
||||
if (!checkFrameBoundary(frame)) {
|
||||
// 起始标识正确,但结束标识不正确,可能是错误的数据
|
||||
// qWarning() << "Message::extractFrame - 帧边界检查失败";
|
||||
consumedBytes = startPos + 1; // 跳过这个错误的起始标识
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
consumedBytes = startPos + frameSize;
|
||||
return frame;
|
||||
}
|
||||
|
||||
// 读取数据长度
|
||||
quint16 Message::readLength(const QByteArray &frame)
|
||||
{
|
||||
if (frame.size() < HEADER_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
return head.length;
|
||||
}
|
||||
|
||||
// 检查帧边界
|
||||
bool Message::checkFrameBoundary(const QByteArray &frame)
|
||||
{
|
||||
if (frame.size() < MIN_FRAME_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查起始标识
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
if (!head.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查结束标识
|
||||
int dataLength = head.length;
|
||||
|
||||
if (frame.size() < HEADER_SIZE + dataLength + TRAILER_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MsgTail tail;
|
||||
memcpy(&tail, frame.constData() + HEADER_SIZE + dataLength, TRAILER_SIZE);
|
||||
return tail.isValid();
|
||||
}
|
||||
|
||||
#include "message.h"
|
||||
|
||||
Message::Message(QObject *parent)
|
||||
{
|
||||
FRAME_START = 0x2B; // '+'
|
||||
FRAME_END = 0x3C; // '<'
|
||||
HEADER_SIZE = 4; // 1(起始) + 2(长度) + 1(预留)
|
||||
TRAILER_SIZE = 1; // 1(结束)
|
||||
MIN_FRAME_SIZE = HEADER_SIZE + TRAILER_SIZE; // 5字节
|
||||
}
|
||||
|
||||
Message::~Message()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QByteArray Message::pack(const QByteArray &data)
|
||||
{
|
||||
// 检查数据长度
|
||||
if (data.size() > 65535) {
|
||||
//Message::pack - 数据长度超过65535字节限制
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
// 创建协议头
|
||||
MsgHead head;
|
||||
head.start = FRAME_START;
|
||||
head.reserved = 0;
|
||||
// 只保存实际内容的长度
|
||||
head.length = static_cast<quint16>(data.size());
|
||||
// head.toNetworkOrder(); // 转换为大端序
|
||||
|
||||
// 创建协议尾
|
||||
MsgTail tail;
|
||||
tail.end = FRAME_END;
|
||||
|
||||
// 构建完整帧
|
||||
QByteArray frame;
|
||||
frame.reserve(HEADER_SIZE + data.size() + TRAILER_SIZE);
|
||||
|
||||
// 添加头部
|
||||
frame.append(reinterpret_cast<const char*>(&head), HEADER_SIZE);
|
||||
|
||||
// 添加数据
|
||||
if (!data.isEmpty()) {
|
||||
frame.append(data);
|
||||
}
|
||||
|
||||
// 添加尾部
|
||||
frame.append(reinterpret_cast<const char*>(&tail), TRAILER_SIZE);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
bool Message::unpack(const QByteArray &frame, QByteArray &data)
|
||||
{
|
||||
if (!validate(frame)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查数据长度
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
|
||||
quint16 dataLength = head.length;
|
||||
int expectedSize = HEADER_SIZE + dataLength + TRAILER_SIZE;
|
||||
|
||||
if (frame.size() < expectedSize) {
|
||||
// 帧不完整
|
||||
return false;
|
||||
}
|
||||
|
||||
// 提取数据
|
||||
data = frame.mid(HEADER_SIZE, dataLength);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Message::validate(const QByteArray &frame)
|
||||
{
|
||||
// 检查最小长度
|
||||
if (frame.size() < MIN_FRAME_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 读取头部
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
|
||||
// 验证起始标识
|
||||
if (!head.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
quint16 dataLength = head.length;
|
||||
|
||||
// 读取尾部
|
||||
MsgTail tail;
|
||||
memcpy(&tail, frame.constData() + HEADER_SIZE + dataLength, TRAILER_SIZE);
|
||||
|
||||
// 验证结束标识
|
||||
if (!tail.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QByteArray Message::extractFrame(const QByteArray &buffer, int &consumedBytes)
|
||||
{
|
||||
consumedBytes = 0;
|
||||
|
||||
// 查找起始标识
|
||||
int startPos = buffer.indexOf(FRAME_START);
|
||||
if (startPos < 0) {
|
||||
return QByteArray(); // 没有找到起始标识
|
||||
}
|
||||
|
||||
// 检查是否有完整的头部
|
||||
if (startPos + HEADER_SIZE > buffer.size()) {
|
||||
return QByteArray(); // 头部不完整
|
||||
}
|
||||
|
||||
// 读取数据长度
|
||||
quint16 dataLength = readLength(buffer.mid(startPos, HEADER_SIZE));
|
||||
|
||||
// 计算完整帧大小
|
||||
int frameSize = HEADER_SIZE + dataLength + TRAILER_SIZE;
|
||||
|
||||
// 检查是否有完整的帧
|
||||
if (startPos + frameSize > buffer.size()) {
|
||||
return QByteArray(); // 帧不完整
|
||||
}
|
||||
|
||||
// 提取并验证完整帧
|
||||
QByteArray frame = buffer.mid(startPos, frameSize);
|
||||
|
||||
if (!checkFrameBoundary(frame)) {
|
||||
// 起始标识正确,但结束标识不正确,可能是错误的数据
|
||||
// qWarning() << "Message::extractFrame - 帧边界检查失败";
|
||||
consumedBytes = startPos + 1; // 跳过这个错误的起始标识
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
consumedBytes = startPos + frameSize;
|
||||
return frame;
|
||||
}
|
||||
|
||||
// 读取数据长度
|
||||
quint16 Message::readLength(const QByteArray &frame)
|
||||
{
|
||||
if (frame.size() < HEADER_SIZE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
return head.length;
|
||||
}
|
||||
|
||||
// 检查帧边界
|
||||
bool Message::checkFrameBoundary(const QByteArray &frame)
|
||||
{
|
||||
if (frame.size() < MIN_FRAME_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查起始标识
|
||||
MsgHead head;
|
||||
memcpy(&head, frame.constData(), HEADER_SIZE);
|
||||
if (!head.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查结束标识
|
||||
int dataLength = head.length;
|
||||
|
||||
if (frame.size() < HEADER_SIZE + dataLength + TRAILER_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MsgTail tail;
|
||||
memcpy(&tail, frame.constData() + HEADER_SIZE + dataLength, TRAILER_SIZE);
|
||||
return tail.isValid();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user