【qt】通过TCP传输json,json里包含图像

主要是使用协议头
发送方

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921978.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

四,基础开发工具(下)

4.5自动构建make/Makefile4.5.1基本使用1示例2进一步解释3实践4最佳实践4.6练习&#xff1a;进度条4.6.1倒计时4.6.2进度条version14.6.2进度条version24.7版本控制器Git4.7.1git操作1操作一次&#xff0c;以后不愁2经典"三件套"3常用4版本回退4.7.2小结4.5自动构建m…

C++基本数据类型的范围

文章目录不同位数的系统下各个类型所占字节数如何存储的我发现我能搜到的相关文章都只讲了这些数据类型的范围是这样的&#xff0c;不说实际的存储情况&#xff0c;当你了解了类型实际是如何存储的&#xff0c;再去记忆这些范围就简单了&#xff0c;所以就有了这篇文章不同位数…

基于社交媒体数据的公众情绪指数构建与重大事件影响分析

一、引言在信息爆炸的时代&#xff0c;社交媒体&#xff08;如微博、Twitter&#xff09;已成为公众表达情绪、讨论热点事件的主要平台。通过分析社交媒体数据&#xff0c;可以构建公众情绪指数&#xff0c;并进一步研究其与股市波动、政策发布等重大事件的关联性。本文将介绍如…

OpenLayers数据源集成 -- 章节七:高德地图集成详解

前言在前面的文章中&#xff0c;我们学习了OpenLayers的瓦片调试&#xff08;VectorTileDebug&#xff09;技术。本文将深入探讨OpenLayers中高德地图的集成方法&#xff0c;这是WebGIS开发中接入商业地图服务的重要技术。高德地图作为国内领先的地图服务提供商&#xff0c;提供…

海外代理IP平台Top3评测:LoongProxy、神龙动态IP、IPIPGO哪家更适合你?

在当今互联网环境中&#xff0c;代理IP服务已成为许多企业和个人用户的刚需。无论是数据采集、市场调研还是账号管理&#xff0c;优质的代理IP都能大幅提升工作效率。本文将针对LoongProxy、神龙海外动态IP和IPIPGO这三家主流代理IP服务商进行横向评测&#xff0c;帮助你根据自…

对浏览器事件机制的理解

浏览器事件是什么&#xff1a; 事件是用户操作网页时发生的交互动作&#xff0c;比如 click/move&#xff0c; 事件除了用户触发的动作外&#xff0c;还可以是文档加载&#xff0c;窗口滚动和大小调整。事件被封装成一个 event 对象&#xff0c;包含了该事件发生时的所有相关信…

XCVP1902-2MSEVSVA6865 AMD 赛灵思 XilinxVersal Premium FPGA

XCVP1902-2MSEVSVA6865 是 AMD 赛灵思&#xff08;Xilinx&#xff09;Versal Premium FPGA 系列中的高端自适应系统级芯片&#xff08;Adaptive SoC&#xff09;变体&#xff0c;面向需要极高逻辑密度、海量 I/O 与超高速收发能力的数据中心互联、原型验证与高性能网络加速等应…

kotlin - 2个Fragment实现左右显示,左边列表,右边详情,平板横、竖屏切换(一)

kotlin - 2个Fragment实现左右显示&#xff0c;左边列表&#xff0c;右边详情&#xff0c;平板横、竖屏切换(要使用平板测试)平板横屏&#xff1a;左右fragment实现分屏效果&#xff0c;平板竖屏&#xff1a;只显示左边的fragment&#xff0c;点击才显示右边fragment屏幕旋转&a…

推荐系统中的AB测试:从设计到分析全流程

推荐系统中的AB测试:从设计到分析全流程 关键词:推荐系统、AB测试、实验设计、数据分析、效果评估、统计显著性、用户体验 摘要:本文将深入探讨推荐系统中AB测试的全流程,从实验设计到结果分析。我们将用通俗易懂的方式解释AB测试的核心概念,展示如何科学地评估推荐算法改…

【go语言 | 第1篇】Go环境安装+go语言特性

文章目录go开发环境1. 下载安装包2. 配置环境变量3. GOPROXYgo语言特性1. go的优势2. go适合做什么3. go缺点编写一个go程序注&#xff1a;在VSCode中补全go代码go开发环境 我这里是windows操作系统的环境安装&#xff0c;其他系统可以查看菜鸟教程&#xff1a;Go 语言环境安装…

【Pywinauto库】0. Pywinauto Windows GUI 自动化指南

概述 Pywinauto 是一个用于自动化 Windows GUI 应用程序的 Python 库&#xff0c;适用于自动化测试、数据录入和其他重复性桌面操作。 快速参考表方面方法/属性示例说明安装pip install pywinauto安装库后端选择Application(backend"uia") 或 Application(backend&qu…

CStringArray 和 CStringList

CStringArray 和 CStringList 都是 MFC 中用于管理字符串集合的类&#xff0c;但它们的内部数据结构和适用场景有显著差异&#xff0c;选择时需根据具体操作需求决定。以下从核心区别、功能对比和适用场景三个方面详细说明&#xff1a;一、核心区别&#xff1a;数据结构决定特性…

2025版基于springboot的企业考勤管理系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

设计模式(C++)详解—单例模式(1)

<摘要> 单例模式是创建型设计模式中最经典且应用最广泛的设计模式之一&#xff0c;它确保一个类只有一个实例并提供全局访问点。本文从历史背景和核心概念出发&#xff0c;详细阐述了单例模式的产生背景和演进历程&#xff0c;深入剖析了其在资源管理、状态一致性和访问控…

将GitHub远程仓库修改为ssh

8 将GitHub远程仓库修改为ssh 文章目录8 将GitHub远程仓库修改为ssh1 创建本地的ssh密钥2 设置GitHub密钥3 将本地库链接到远程仓库很多时候在使用GitHub的远程链接使用的是http的格式&#xff0c;但是这个格式并不好&#xff0c;尤其是在代码上传的时候&#xff0c;因此需要采…

【OEC-Turbo】网心云 OEC-Turbo 刷机 Armbian 系统教程

前言 大量网心云 OEC 及 OEC-Turbo 设备流入二手市场&#xff08;如海鲜市场&#xff09;&#xff0c;价格低至 70-100 元。相比同配置的拾光坞 N3&#xff08;约 380 元&#xff09;&#xff0c;OEC-Turbo 仅需一个零头&#xff0c;性价比极高。这些“矿渣”设备外观与玩客云…

25.线程概念和控制(二)

一、线程周边问题1.线程的优点创建一个新线程的代价要比创建一个新进程小得多。线程占用的资源要比进程少很多。能充分利用多处理器的可并行数量。在等待慢速I/O操作结束的同时&#xff0c;程序可执行其他的计算任务。计算密集型应用&#xff0c;为了能在多处理器系统上运行&am…

【CVPR2023】奔跑而非行走:追求更高FLOPS以实现更快神经网络

文章目录一、论文信息二、论文概要三、实验动机四、创新之处五、实验分析六、核心代码注释版本七、实验总结一、论文信息 论文题目&#xff1a;Run, Don’t Walk: Chasing Higher FLOPS for Faster Neural Networks中文题目&#xff1a;奔跑而非行走&#xff1a;追求更高FLOPS…

JVM(二)--- 类加载子系统

目录 前言 一、类加载过程 1. loading阶段 2. Linking阶段 2.1 验证 2.2 准备 2.3 解析 3. Initialization阶段 二、类加载器 1. 类加载器的分类 2. 用户自定义类加载器 三、双亲委派机制 四、其他知识点 前言 JVM的内存结构如图所示&#xff1a; 一、类加载过程…

Docker 容器的使用

1.容器的基本信息[roothost1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9ac8245b5b08 img-layers-test "python /app/app.py" 45 hours ago Exited (0) 45 hour…