Qt中对Udp数据打包发送和接收(续)

这次用一个更加复杂的数据包举例。

心跳报文结构如下:

struct HeartbeatPacket {quint16 protocolId;quint16 version;quint16 totalLength;quint16 reserve;QByteArray senderAddress;QByteArray receiverAddress;quint8 sequenceNumber;quint8 acknowledgementNumber;quint8 messageFlag;quint8 unitCount;quint8 unitNumber;quint8 unitId;QByteArray unitLength;QByteArray timestamp;QByteArray deviceId;QByteArray toByteArray();};

代码如下:

QByteArray HeartbeatPacket::toByteArray() {QByteArray byteArray;QDataStream stream(&byteArray, QIODevice::WriteOnly);// 注意:此处可能需要考虑字节序问题stream << protocolId;stream << version;stream << totalLength;stream << reserve;stream.writeRawData(senderAddress.constData(), senderAddress.size());stream.writeRawData(receiverAddress.constData(), receiverAddress.size());stream << sequenceNumber;stream << acknowledgementNumber;stream << messageFlag;stream << unitCount;stream << unitNumber;stream << unitId;stream.writeRawData(unitLength.constData(), unitLength.size());stream.writeRawData(timestamp.constData(), timestamp.size());stream.writeRawData(deviceId.constData(), deviceId.size());return byteArray;
}void MainWindow::sendHeartbeat(const QHostAddress &address, quint16 port)
{QByteArray packetData = heartbeatPacket.toByteArray();udpSocket.writeDatagram(packetData, address, port);
}void MainWindow::convertVectorToHeartbeatPacket()
{if (dataVector.size() < 13) {qDebug() << "vector size too short.";return;}bool reverseBytes = false;  // 默认字节序为低字节在前auto reverseIter = dataVector[3].find("name");if (reverseIter != dataVector[3].end() && reverseIter->second == "reverse") {auto valueIter = dataVector[3].find("value");if (valueIter != dataVector[3].end()) {QString reverseValue = valueIter->second.toLower();if (reverseValue == "True") {reverseBytes = true;}}}heartbeatPacket.protocolId = dataVector[0].at("value").toUShort();heartbeatPacket.version = dataVector[1].at("value").toUShort();heartbeatPacket.totalLength = dataVector[2].at("value").toUShort();heartbeatPacket.reserve = dataVector[3].at("value").toUShort();// 设置senderAddress和receiverAddress,需要将16进制字符串转换为QByteArray,并根据reverseBytes确定字节序QByteArray senderAddressHex = dataVector[4].at("value").toUtf8();QByteArray receiverAddressHex = dataVector[5].at("value").toUtf8();QByteArray senderAddressBytes;QByteArray receiverAddressBytes;if (reverseBytes) {// 高字节在前的字节序for (int i = senderAddressHex.size() - 2; i >= 0; i -= 2) {senderAddressBytes.append(senderAddressHex.mid(i, 2).toInt(nullptr, 16));receiverAddressBytes.append(receiverAddressHex.mid(i, 2).toInt(nullptr, 16));}} else {// 低字节在前的字节序for (int i = 0; i < senderAddressHex.size(); i += 2) {senderAddressBytes.append(senderAddressHex.mid(i, 2).toInt(nullptr, 16));receiverAddressBytes.append(receiverAddressHex.mid(i, 2).toInt(nullptr, 16));}}heartbeatPacket.senderAddress = senderAddressBytes;heartbeatPacket.receiverAddress = receiverAddressBytes;heartbeatPacket.sequenceNumber = dataVector[6].at("value").toShort();heartbeatPacket.acknowledgementNumber = dataVector[7].at("value").toShort();heartbeatPacket.messageFlag = dataVector[8].at("value").toShort();heartbeatPacket.unitCount = dataVector[9].at("value").toShort();heartbeatPacket.unitNumber = dataVector[10].at("value").toShort();heartbeatPacket.unitId = dataVector[11].at("value").toShort();QByteArray unitLengthHex = dataVector[12].at("value").toUtf8();QByteArray unitLengthBytes;// 低字节在前的字节序for (int i = 0; i < unitLengthHex.size(); i += 2) {unitLengthBytes.append(unitLengthHex.mid(i, 2).toInt(nullptr, 16));}
//    // 高字节在前的字节序
//    for (int i = unitLengthHex.size() - 2; i >= 0; i -= 2) {
//        unitLengthBytes.append(unitLengthHex.mid(i, 2).toInt(nullptr, 16));
//    }heartbeatPacket.unitLength = unitLengthBytes;// 设置timestamp,需要将16进制字符串转换为QByteArrayQByteArray timestampHex = dataVector[13].at("value").toUtf8();QByteArray timestampBytes;if (reverseBytes) {// 高字节在前的字节序for (int i = timestampHex.size() - 2; i >= 0; i -= 2) {timestampBytes.append(timestampHex.mid(i, 2).toInt(nullptr, 16));}} else {// 低字节在前的字节序for (int i = 0; i < timestampHex.size(); i += 2) {timestampBytes.append(timestampHex.mid(i, 2).toInt(nullptr, 16));}}heartbeatPacket.timestamp = timestampBytes;// 设置deviceId,需要将16进制字符串转换为QByteArrayQByteArray deviceIdHex = dataVector[14].at("value").toUtf8();QByteArray deviceIdBytes;if (reverseBytes) {// 高字节在前的字节序for (int i = deviceIdHex.size() - 2; i >= 0; i -= 2) {deviceIdBytes.append(deviceIdHex.mid(i, 2).toInt(nullptr, 16));}} else {// 低字节在前的字节序for (int i = 0; i < deviceIdHex.size(); i += 2) {deviceIdBytes.append(deviceIdHex.mid(i, 2).toInt(nullptr, 16));}}heartbeatPacket.deviceId = deviceIdBytes;
}bool MainWindow::LoadXmlContent(QString FileName)
{QString FilePath = m_selectedFolderPath + "/" + FileName + ".xml";QFile file(FilePath); // 替换为您实际的文件路径if (!file.open(QIODevice::ReadOnly)) {qDebug() << "Can not open file。";return false;}QDomDocument document;if (!document.setContent(&file)) {qDebug() << "无法将文件解析为DOM树。";file.close();return false;}file.close();dataVector.clear();QDomElement root = document.firstChildElement(); // 获取根元素// 遍历所有子元素QDomNodeList elements = root.childNodes();
//            for (int i = 0; i < elements.count(); i++) {
//                    QDomNode elementNode = elements.at(i);
//                    // 检查节点是否为元素。
//                    if (elementNode.isElement()) {
//                        QDomElement element = elementNode.toElement();//                        QDomNodeList childNodes = element.childNodes();
//                        for (int j = 0; j < childNodes.count(); j++) {
//                            QDomNode childNode = childNodes.at(j);
//                            if (childNode.isElement()) {
//                                QDomElement childElement = childNode.toElement();
//                                qDebug() << childElement.nodeName() << ":" << childElement.text();
//                            }
//                        }
//                    }
//            }for (int i = 0; i < elements.count(); i++) {QDomNode elementNode = elements.at(i);// 检查节点是否为元素。if (elementNode.isElement()) {QDomElement element = elementNode.toElement();QDomNodeList childNodes = element.childNodes();// 创建一个字典来存储键值对std::map<QString, QString> dataMap;for (int j = 0; j < childNodes.count(); j++) {QDomNode childNode = childNodes.at(j);if (childNode.isElement()) {QDomElement childElement = childNode.toElement();
//                                QString key = childElement.nodeName();QString key = childElement.nodeName();// 将键的第一个字母转换为小写if (!key.isEmpty()) {key[0] = key[0].toLower();}QString value = childElement.text();// 将键值对存入字典dataMap[key] = value;}}// 将字典存入vectordataVector.push_back(dataMap);}}// 打印存储的数据for (const auto& data : dataVector) {for (const auto& pair : data) {qDebug() << pair.first << ":" << pair.second;}qDebug() << "-------------------";}
}void MainWindow::onSendButtonClicked()
{LoadXmlContent("心跳报文");convertVectorToHeartbeatPacket();// 发送心跳报文到广播地址sendHeartbeat(QHostAddress::Broadcast, 12345);
}

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

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

相关文章

MVCC-

文章目录 1. 什么是MVCC2. 快照读和当前读3. 复习4. MVCC实现原理之ReadView5. 总结 文章目录 1. 什么是MVCC2. 快照读和当前读3. 复习4. MVCC实现原理之ReadView5. 总结 1. 什么是MVCC 口述&#xff1a;MVCC其实他是解决这种读-写的情况的&#xff0c;当然读-写也可以用 锁来…

医保支付方式探索——利益共享机制的文章分析

Care-coordination: Gain-sharing Agreements in Bundled Payment Models 分析一下这篇文章&#xff0c;这篇文章于2021年发表在POMS上&#xff0c;但是引用量没有那么高。这篇文章涉及到医疗捆绑支付&#xff0c;应该可以学习一下。 文章研究一个在一个以最小成本为目标的质…

python+Appium自动化:python多线程多并发启动appium服务

Python启动Appium 服务 使用Dos命令或者bat批处理来手动启动appium服务&#xff0c;启动效率低下。如何将启动Appium服务也实现自动化呢&#xff1f; 这里需要使用subprocess模块&#xff0c;该模块可以创建新的进程&#xff0c;并且连接到进程的输入、输出、错误等管道信息&…

oj塞氪算法练习

向量点积计算 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();int[] a new int[n];int[] b new int[n];for (int i 0; i < n; i) {a[i] scanner.nextInt();}…

汇编语言实现音乐播放器

目标程序 用汇编语言实现一个音乐播放器&#xff0c;并支持点歌 Overview 乐曲是按照一定的高低、长短和强弱关系组成的音调&#xff0c;在一首乐曲中&#xff0c;每个音符的音高和音长与频率和节拍有关&#xff0c;因此我们要分别为3首要演奏的乐曲定义一个频率表和一个节拍…

jenkins使用nexus插件

nexus介绍 Nexus 是一个强大的仓库管理工具&#xff0c;用于管理和分发 Maven、npm、Docker 等软件包。它提供了一个集中的存储库&#xff0c;用于存储和管理软件包&#xff0c;并提供了版本控制、访问控制、构建和部署等功能。 Nexus 可以帮助开发团队提高软件包管理的效率和…

解决element ui tree组件不产生横向滚动条

结果是这样的 需要在tree的外层&#xff0c;包一个父组件 <div class"tree"><el-tree :data"treeData" show-checkbox default-expand-all></el-tree></div> 在css里面这样写,样式穿透按自己使用的css编译器以及框架要求就好 &l…

使用waitress与nginx在腾讯云上进行flask项目部署

1.首先介绍一下waitress与nginx是啥&#xff0c; Waitress: 类别&#xff1a; Waitress 是一个用于 Python Web 应用程序的 WSGI&#xff08;Web Server Gateway Interface&#xff09;服务器。WSGI 是 Python Web 应用程序和 Web 服务器之间的标准接口&#xff0c;允许开发人员…

什么是Ros(一)- 名词解释和架构概述

目录 1.概述 2.名词解释 2.1节点&#xff08;Node&#xff09; 2.2节点管理器&#xff08;Master&#xff09; 2.3消息&#xff08;Message&#xff09; 2.4话题&#xff08;Topic&#xff09; 2.5服务&#xff08;Service&#xff09; 2.6动作&#xff08;Action&#…

基于Logistic回归实现二分类

目录 Logistic回归公式推导&#xff1a; Sigmoid函数&#xff1a; Logistic回归如何实现分类&#xff1a; 优化的方法&#xff1a; 代码&#xff1a; 1.创建一个随机数据集&#xff0c;分类直线为y2x&#xff1a; 为什么用np.hstack()增加一列1&#xff1f; 为什么返回…

Spring | Spring的基本应用

目录: 1.什么是Spring&#xff1f;2.Spring框架的优点3.Spring的体系结构 (重点★★★) :3.1 Core Container (核心容器) ★★★Beans模块 (★★★) : BeanFactoryCore核心模块 (★★★) : IOCContext上下文模块 (★★★) : ApplicationContextContext-support模块 (★★★)SpE…

[传智杯 #3 练习赛] 直角三角形

题目描述 一个直角三角形的两个直角边是a,b(a≤b)&#xff0c;其斜边是 c&#xff0c;且 a,b,c 都是正整数。 现在我们已经知道了斜边长度 c&#xff0c;请问这个直角三角形的两个直角边的长度是什么&#xff1f; 输入格式 输入一个整数 c(1≤c≤1.41104)。 输出格式 输出…

【Erlang进阶学习】4、进程与消息传递

在Erlang系统中&#xff0c;进程都是轻量级的&#xff0c;意味着创建进程只需要花费微不足道的时间和极少的内存。 1、进程间不共享内存&#xff0c;而是通过消息传递来通信。 2、消息从发送进程的栈上复制到接收进程的堆上。 3、由于多个进程并发地在独立的内存空间执行&#…

RocketMQ- 深入理解RocketMQ的消息模型

1、RocketMQ客户端基本流程 ​ RocketMQ基于Maven提供了客户端的核心依赖&#xff1a; <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.9.5</version> </dependency&…

PyQt6 QCheckBox复选框按钮控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计33条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

Three.js的THREE.LOD如何加载gltf模型

要在Three.js中使用THREE.LOD加载gltf模型&#xff0c;可以按照以下步骤操作&#xff1a; 1、首先&#xff0c;确保已经引入了Three.js库和GLTFLoader插件。可以通过以下方式引入&#xff1a; <script src"https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/thre…

idea通过remote远程调试云服务器

引用了第三方的包&#xff0c;调试是看不到运行流程&#xff0c;于是想到了idea的remote方法 -agentlib:jdwptransportdt_socket,servery,suspendn,address9002 写一个.sh文件并启动 nohup java -jar -agentlib:jdwptransportdt_socket,servery,suspendn,address9002 ./demo.j…

【Socket】Unix环境下搭建局域网内TCP服务端

本文搭建一个简单的、Unix环境下的、局域网内的TCP服务端&#xff1a;每当有客户端连接时&#xff0c;打印一下对方的ip地址及端口号。 本文要学习的Unix网络IPC的套接字函数&#xff1a; socketbindlistenaccept 本文要学习的一些工具函数&#xff1a; inet_ptonhtonsgets…

基本面选股的方法

基本面选股是一种投资策略&#xff0c;主要关注公司的财务状况、盈利能力、行业地位等因素&#xff0c;以判断公司的价值并做出投资决策。以下是基本面选股的具体分析方法和重点&#xff1a; 财务状况分析&#xff1a; 利润表分析&#xff1a;关注公司的净利润、毛利率、营业…