主要是使用协议头
发送方
connect(m_pDetectWorker, &DetectionWorker::sig_detectImg, this, [=](const QJsonObject &json){
// 转换为JSON数据
QJsonDocument doc(json);
QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
// 构建增强协议头
struct EnhancedHeader {
quint32 magic = 0x4A534F4E; // "JSON"
quint32 version = 1; // 协议版本
quint32 dataSize;
quint32 checksum;
quint8 dataType; // 0=JSON, 1=Image, 2=Text等
char timestamp[20]; // 时间戳
char reserved[15];
};
EnhancedHeader header;
header.dataSize = jsonData.size();
header.dataType = 0; // JSON数据类型
// 计算校验和
quint32 checksum = 0;
for (int i = 0; i < jsonData.size(); ++i) {
checksum += static_cast<quint8>(jsonData[i]);
}
header.checksum = checksum;
// 添加时间戳
QByteArray timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").toUtf8();
memcpy(header.timestamp, timestamp.constData(), qMin(timestamp.size(), 19));
header.timestamp[19] = '\0';
memset(header.reserved, 0, sizeof(header.reserved));
// 发送给所有客户端
foreach(QTcpSocket* client, clients) {
if(client->state() == QAbstractSocket::ConnectedState) {
client->setSocketOption(QAbstractSocket::LowDelayOption, 1);
// 发送协议头
client->write(reinterpret_cast<const char*>(&header), sizeof(header));
// 发送JSON数据
client->write(jsonData);
}
}
});
接收方
void OnlineFrameViewModel::receiveImageData()
{
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
if(!socket) return;
// 定义协议头结构(与发送端一致)
struct EnhancedHeader {
quint32 magic; // 魔数 "JSON"
quint32 version; // 协议版本
quint32 dataSize; // 数据大小
quint32 checksum; // 校验和
quint8 dataType; // 数据类型
char timestamp[20]; // 时间戳
char reserved[15]; // 保留字段
};
static QByteArray receivedDataBuffer;
receivedDataBuffer.append(socket->readAll());
// 处理可能存在的多个数据包(粘包处理)
while (!receivedDataBuffer.isEmpty()) {
// 如果缓冲区大小不足以包含协议头,等待更多数据
if (receivedDataBuffer.size() < sizeof(EnhancedHeader)) {
return;
}
// 提取协议头
EnhancedHeader header;
memcpy(&header, receivedDataBuffer.constData(), sizeof(EnhancedHeader));
// 验证魔数
if (header.magic != 0x4A534F4E) { // "JSON"
qDebug() << u8"无效的数据包魔数,清空缓冲区";
receivedDataBuffer.clear();
return;
}
// 检查是否收到完整的数据包(协议头 + 数据)
if (receivedDataBuffer.size() < sizeof(EnhancedHeader) + header.dataSize) {
// 数据不完整,等待更多数据
return;
}
// 提取JSON数据
QByteArray jsonData = receivedDataBuffer.mid(sizeof(EnhancedHeader), header.dataSize);
// 验证校验和
quint32 calculatedChecksum = 0;
for (int i = 0; i < jsonData.size(); ++i) {
calculatedChecksum += static_cast<quint8>(jsonData[i]);
}
if (calculatedChecksum != header.checksum) {
qDebug() << u8"数据校验失败,丢弃数据包";
// 移除损坏的数据包
receivedDataBuffer.remove(0, sizeof(EnhancedHeader) + header.dataSize);
continue;
}
// 移除已处理的数据包
receivedDataBuffer.remove(0, sizeof(EnhancedHeader) + header.dataSize);
// 解析JSON数据
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &jsonError);
if(jsonError.error != QJsonParseError::NoError) {
qDebug() << u8"JSON解析错误:" << jsonError.errorString();
continue;
}
if(jsonDoc.isObject()) {
QJsonObject jsonObj = jsonDoc.object();
// 处理图像数据(原有逻辑保持不变)
if(jsonObj.contains("image_path")) {
QString jsonOriPath = jsonObj["image_path"].toString();//原始路径,pc1的路径
QString imgPath;
// 指定检测 E 盘
QStorageInfo volume("Y:/");
if (volume.isValid()) {
// 双工控机测试是肯定存在
imgPath = jsonOriPath.replace(u8"E:/raw图/","Y:/");
emit sig_sendMsg(u8"检测路径:"+ imgPath);
QFileInfo fileInfo(imgPath);
if (!fileInfo.exists()) {
qCritical() << "Error: Path does not exist:" << imgPath;
continue; // 继续处理下一个数据包
}
} else {
emit sig_sendMsg("Y:/ is not a valid volume.");
imgPath = jsonOriPath;
emit sig_sendMsg(u8"Y盘读取失败,检查PLC网口的网络情况");
emit sig_sendMsg(u8"检测路径:"+ imgPath);
QFileInfo fileInfo(imgPath);
if (!fileInfo.exists()) {
qCritical() << "Error: Path does not exist:" << imgPath;
continue; // 继续处理下一个数据包
}
}
QImage enhanceImg(imgPath);
//=============================👇=============================
if(jsonObj.contains("image_data")) {
QString base64String = jsonObj["image_data"].toString();
QByteArray byteArray = QByteArray::fromBase64(base64String.toUtf8());
QImage img;
if (img.loadFromData(byteArray)) {
qDebug() << u8"图片加载成功,尺寸为:" << img.size();
enhanceImg = img;
} else {
qDebug() << u8"图片加载失败";
}
}
//=============================👆=============================
QSharedPointer<ImageDataInfo> imgInfo(new ImageDataInfo);
imgInfo->imageFilePath = imgPath;
imgInfo->enhanceImg = enhanceImg;
imgInfo->barcode = jsonObj["barcode"].toString();
imgInfo->device = jsonObj["device"].toInt();
imgInfo->pointIndex = jsonObj["pointIndex"].toInt();
imgInfo->skipframe = jsonObj["skipframe"].toInt();
imgInfo->overlayframe = jsonObj["overlayframe"].toInt();
imgInfo->kv = jsonObj["kv"].toInt();
imgInfo->ua = jsonObj["ua"].toInt();
imgInfo->grayMean = jsonObj["grayMean"].toInt();
emit sig_sendMsg(u8"检测开始"+imgInfo->barcode);
int device = imgInfo->pointIndex;
int pointIndex = imgInfo->pointIndex;
QtConcurrent::run([=]() {
saveBarcodeLog(imgInfo->barcode,device,pointIndex);
});
if(m_pDetectWorker!=nullptr)
m_pDetectWorker->enqueueImage(*imgInfo);
emit sig_didDisplayLiveImg(enhanceImg,imgInfo->device);
}
}
}
}