Qt 实现网络数据报文大小端数据的收发

1.大小端数据简介

大小端(Endianness)是计算机体系结构的一个术语,它描述了多字节数据在内存中的存储顺序。以下是大小端的定义和它们的特点:

大端(Big-Endian)
在大端模式中,一个字的最高有效字节(MSB,即最左边的那位)存储在最低的内存地址处,而最低有效字节(LSB,即最右边的那位)存储在最高的内存地址处。

例如,假设有一个16位的数字 0x1234,其在内存中的存储顺序如下:

地址增加方向 -->

[ 12 ] [ 34 ]

其中 [12] 是高字节,存储在低地址处;[34] 是低字节,存储在高地址处。

小端(Little-Endian)
在小端模式中,情况正好相反:一个字的最低有效字节存储在最低的内存地址处,而最高有效字节存储在最高的内存地址处。

继续上面的例子,16位的数字 0x1234 在小端模式下的存储顺序如下:

地址增加方向 -->

[ 34 ] [ 12 ]

其中 [34] 是低字节,存储在低地址处;[12] 是高字节,存储在高地址处。

2.小端数据收发

假设我们现在有一个UDP头的数据结构如下所示。

    //UDP协议头
    typedef struct
    {
        quint16 type;               //报文类型
        quint16 num;                //报文序号,取值范围为0~65535
        quint32 len;                //报文长度
        quint16 srcAddr;            //信源地址
        quint16 dstAddr;            //信宿地址
        quint8  year;               //发送时间  年份后两位   UTC时间
        quint8  month;
        quint8  day;
        quint8  hour;
        quint8  minute;
        quint8  second;
    }UdpHeader;

数据发送:组包。

QByteArray pack(const Protocol::UdpHeader &header)
{
    QByteArray byte;
    byte.append((char*)&(header.type),2);
    byte.append((char*)&(header.num),2);
    byte.append((char*)&(header.len),4);
    byte.append((char*)&(header.srcAddr),2);
    byte.append((char*)&(header.dstAddr),2);

    QString format = "yy-MM-dd-hh-mm-ss";
    QDateTime dateTime = QDateTime::currentDateTime();
    dateTime.setTimeSpec(Qt::LocalTime);

    QDateTime utcTime = dateTime.toUTC();

    QString strUtcTime = utcTime.toString(format);

    QStringList timeList = strUtcTime.split('-');

    quint8 year = timeList.at(0).toInt();
    quint8 month = timeList.at(1).toInt();
    quint8 day = timeList.at(2).toInt();
    quint8 hour = timeList.at(3).toInt();
    quint8 minute = timeList.at(4).toInt();
    quint8 sec = timeList.at(5).toInt();

    byte.append(year);
    byte.append(month);
    byte.append(day);
    byte.append(hour);
    byte.append(minute);
    byte.append(sec);

    return byte;
}

数据接收:拆包

void unPack(const QByteArray &byte, Protocol::UdpHeader &header)
{
    if(byte.size() != UDP_HEADER_LEN)
    {
        return;
    }

    memcpy(&header,byte.data(),sizeof(Protocol::UdpHeader));
}

3.大端数据收发

还是上面的头例子。
数据发送:组包。
使用QDataStream类作为辅助,设置setByteOrder为大端序列。

QByteArray packBigEndian(const Protocol::UdpHeader &header)
{
    QByteArray byte;
    QDataStream stream(&byte,QIODevice::WriteOnly);
    stream.setByteOrder(QDataStream::BigEndian);

    stream<<(header.type);
    stream<<(header.num);
    stream<<(header.len);
    stream<<(header.srcAddr);
    stream<<(header.dstAddr);

    QString format = "yy-MM-dd-hh-mm-ss";
    QDateTime dateTime = QDateTime::currentDateTime();
    dateTime.setTimeSpec(Qt::LocalTime);

    QDateTime utcTime = dateTime.toUTC();

    QString strUtcTime = utcTime.toString(format);

    QStringList timeList = strUtcTime.split('-');

    quint8 year = timeList.at(0).toInt();
    quint8 month = timeList.at(1).toInt();
    quint8 day = timeList.at(2).toInt();
    quint8 hour = timeList.at(3).toInt();
    quint8 minute = timeList.at(4).toInt();
    quint8 sec = timeList.at(5).toInt();

    stream<<year;
    stream<<month;
    stream<<day;
    stream<<hour;
    stream<<minute;
    stream<<sec;

    return byte;
}

数据接收:拆包。
对于多字节的数据,都需要单独使用qToBigEndian转换为大端。

void unPackBigEndian(const QByteArray &byte, Protocol::UdpHeader &header)
{
    if(byte.size() != UDP_HEADER_LEN)
    {
        return;
    }

    memcpy(&header,byte.data(),sizeof(Protocol::UdpHeader));
    header.type = qToBigEndian(header.type);
    header.num= qToBigEndian(header.num);
    header.len= qToBigEndian(header.len);
    header.srcAddr= qToBigEndian(header.srcAddr);
    header.dstAddr= qToBigEndian(header.dstAddr);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

速度革命:esbuild如何改变前端构建游戏 (1)

什么是 esbuild&#xff1f; esbuild 是一款基于 Go 语言开发的 JavaScript 构建打包工具&#xff0c;以其卓越的性能著称。相比传统的构建工具&#xff08;如 Webpack&#xff09;&#xff0c;esbuild 在打包速度上有着显著的优势&#xff0c;能够将打包速度提升 10 到 100 倍…

Ros Noetic 20.04 跑通mpc_ros包保姆级教程

前言: 本文将简述mpc_ros包在noetic20.04中的安装,mpc是 一种跟踪、MPC_ROS 是一个基于ROS(Robot Operating System)的模型预测控制(Model Predictive Control,MPC)库。该项目旨在为机器人控制提供一个灵活且高效的MPC实现,使得开发者能够在ROS环境中轻松集成和使用MPC…

接上一主题,C++14中如何设计类似于std::any,使集合在C++中与Python一样支持任意数据?

这篇文章的重点是C多态的应用&#xff0c;但是如果你是C新手&#xff0c; 你需要了解以下C知识&#xff1a; 类 构造函数 拷贝构造函数 虚拟函数 纯虚拟函数 析构函数 类的继承 运算符重写 模板类 模板参数 数组 数组的传递 指针与动态内存分配 Python&#xff1a; s …

AndroidStudio与开发板调试时连接失败或APP闪退的解决方案,涉及SELINUX及获取Root权限

现象 用AndroidStudio打开工程代码,点击运行后,报错: 解决方案 具体原因是尝试运行 su(通常用于获取超级用户权限)时失败了,提示 “Permission denied” 通过 CONFIG_SECURITY_SELINUX 变量控制 SElinux 开启或关闭 在vim /rk3568_android_sdk/device/rockchip/rk…

数据结构 (6)栈的应用举例

1. 递归调用 递归函数在执行时&#xff0c;会将每一层的函数调用信息&#xff08;包括局部变量、参数和返回地址&#xff09;存储在栈中。当递归函数返回时&#xff0c;这些信息会从栈中弹出&#xff0c;以便恢复之前的执行状态。栈的后进先出&#xff08;LIFO&#xff09;特性…

QT 网络编程 数据库模块 TCP UDP QT5.12.3环境 C++实现

一、网络编程 1. 模块引入 QT network 2. 头文件 #include <QTcpServer> //TCP服务端使用 #include <QTcpSocket> //TCP服务器和客户端都使用 3. TCP网络编程流程 1) 服务端 实例化QTcpServer对象----------------------------->socket 进入监听状态…

使用ENSP实现NAT

一、项目拓扑 二、项目实现 1.路由器AR1配置 进入系统试图 sys将路由器命名为R1 sysname R1关闭信息中心 undo info-center enable进入g0/0/0接口 int g0/0/0将g0/0/0接口IP地址配置为12.12.12.1/30 ip address 12.12.12.1 30进入e0/0/1接口 int g0/0/1将g0/0/1接口IP地址配置…

Python的tkinter如何把日志弄进文本框(Text)

当我们用python的Tkinter包给程序设计界面时&#xff0c;在有些时候&#xff0c;我们是希望程序的日志显示在界面上的&#xff0c;因为用户也需要知道程序目前运行到哪一步了&#xff0c;以及程序当前的运行状态是否良好。python的通过print函数打印出来的日志通常显示在后台&a…

flux的版本

1.flux1-dev.safetensors https://huggingface.co/black-forest-labs/FLUX.1-devhttps://huggingface.co/black-forest-labs/FLUX.1-dev原生的23.8G的模型。原生12B的模型,float16的。需要配合ae.safetensors,flux1-dev.safetensors以及clip-l和T5的权重使用,注意ae.sft和f…

阿里云私服地址

1.解压apache-maven-3.6.1-bin 2.配置本地仓库&#xff1a;修改conf/dettings.xml中的<localReoisitory>为一个指定目录。56行 <localRepository>D:\apache-maven-3.6.1-bin\apache-maven-3.6.1\mvn_repo</localRepository> 3.配置阿里云私服&#xff1a;…

【大数据学习 | Spark-Core】yarn-client与yarn-cluster的区别

1. yarn的提交命令 # yarn的提交命令参数 --master yarn #执行集群 --deploy-mode # 部署模式 --class #指定运行的类 --executor-memory #指定executor的内存 --executor-cores # 指定核数 --num-executors # 直接指定executor的数量 --queue # 指定队列 2. yarn-client模式…

【汽车制动】汽车制动相关控制系统

目录 1.ABS (Anti-lock Brake System&#xff0c;防抱死制动系统) 2.EBD&#xff08;Electronic Brake-force Distribution&#xff0c;电子制动力分配系统&#xff09; 3.TCS&#xff08;Traction Control System&#xff0c;牵引力控制系统&#xff09; 4.VDC&#xff08…

《TCP/IP网络编程》学习笔记 | Chapter 15:套接字与标准 I/O

《TCP/IP网络编程》学习笔记 | Chapter 15&#xff1a;套接字与标准 I/O 《TCP/IP网络编程》学习笔记 | Chapter 15&#xff1a;套接字与标准 I/O标准 I/O 函数标准 I/O 函数的两个优点标准 I/O 函数和系统函数之间的性能对比标准 I/O 函数的几个缺点 使用标准 I/O 函数利用 fd…

<OS 有关> ubuntu 24 不同版本介绍 安装 Vmware tools

原因 想用 apt-get download 存到本地 / NAS上&#xff0c;减少网络流浪。 看到 VMware 上的确实有 ubuntu&#xff0c;只是版本是16。 ubuntu 版本比较&#xff1a;LTS vs RR LTS: Long-Term Support 长周期支持&#xff0c; 一般每 2 年更新&#xff0c;会更可靠与更稳定…

支持多种快充协议和支持多种功能的诱骗取电协议芯片

汇铭达XSP15是一款应用于手持电动工具、智能家居、显示器、音箱等充电方案的大功率快充协议芯片&#xff0c;支持最大功率100W给设备快速充电&#xff0c;大大缩短了充电时间。芯片支持通过UART串口发送电压/电流消息供其它芯片读取。支持自动识别连接的是电脑或是充电器。支持…

【一篇搞定配置】网络分析工具WireShark的安装与入门使用

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;各种软件安装与配置_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1.…

JavaWeb之综合案例

前言 这一节讲一个案例 1. 环境搭建 然后就是把这些数据全部用到sql语句中执行 2.查询所有-后台&前台 我们先写后台代码 2.1 后台 2.2 Dao BrandMapper&#xff1a; 注意因为数据库里面的名称是下划线分割的&#xff0c;我们类里面是驼峰的&#xff0c;所以要映射 …

【STM32】MPU6050初始化常用寄存器说明及示例代码

一、MPU6050常用配置寄存器 1、电源管理寄存器1&#xff08; PWR_MGMT_1 &#xff09; 此寄存器允许用户配置电源模式和时钟源。 DEVICE_RESET &#xff1a;用于控制复位的比特位。设置为1时复位 MPU6050&#xff0c;内部寄存器恢复为默认值&#xff0c;复位结束…

隐私友好型分析平台Plausible Analytics

什么是 Plausible Analytics &#xff1f; Plausible Analytics 是一个简单、轻量级&#xff08;小于1KB&#xff09;、开源且隐私友好的网站分析工具&#xff0c;旨在作为 Google Analytics 的替代品。它不使用 cookies 并且完全符合 GDPR、CCPA 和 PECR 法规&#xff0c;因此…

Flutter:RotationTransition旋转动画

配置vsync&#xff0c;需要实现一下with SingleTickerProviderStateMixinclass _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{// 定义 AnimationController late AnimationController _controller;overridevoid initState() {super…