Qt发送端用自定义结构体发送,接收端QByteArray接收

2023-10-27

**

Qt TCP/UDP 一端用自定义结构体发送消息,一端用QByteArray接收消息

**
用自定义结构体发送消息

void TcpServer::timeOut()
{
    QDateTime nowTime = QDateTime::currentDateTime();

    static int dhIndex = 1;
    for(int index =0;index < tcpClientSocketList.size();index++)
    {
        tcpClientSocket* perClient = tcpClientSocketList.at(index);

        if((dhIndex%2) == 1)
        {
            char data[] = "dh haha";
            char* sendData = new char[sizeof (DHPacketHeadEx)+strlen(data)];
            DHPacketHeadEx* packHead = (DHPacketHeadEx*)sendData;
            packHead->packetType = enPacketType::PACKET_BIG_CONTENT;
            packHead->len = strlen(data);
            //strcpy(packHead->pValue,data);
            memcpy(packHead->pValue,data,strlen(data));
            perClient->write(sendData,sizeof (DHPacketHeadEx)+strlen(data));//发送自定义结构体 PACKET_BIG_CONTENT包
            delete [] sendData;
        }
        else
        {
            char* sendData = new char[sizeof (DHPacketHeadEx)];
            DHPacketHeadEx* packHead = (DHPacketHeadEx*)sendData;
            packHead->packetType = enPacketType::PACKET_HEART_BEAT;
            packHead->len = 0;
            perClient->write(sendData,sizeof (DHPacketHeadEx));//发送自定义结构体 PACKET_HEART_BEAT包
            delete [] sendData;
        }

    }

    dhIndex++;

    qint64 result = lastTime.msecsTo(nowTime);
    if(result > 10000)
    {
        QString info = QString("\r\nmore than 5 Min not receive heart beat packet!");
        int len = info.length();
        emit updateServer(info,len);
        lastTime = nowTime;
    }
}

在接收端用QByteArray接收消息

void Client::slotReceiveData()
{
    while(tcpSocket->bytesAvailable() > 0)
    {
        QByteArray byteArray;
        byteArray.append(tcpSocket->readAll());//用readAll读取QByteArray到byteArray里,然后进行解析
        if(byteArray.length() >= sizeof (DHPacketHeadEx))
        {

            //DHPacketHeadEx* packetEx = (DHPacketHeadEx*)(byteArray.toStdString().c_str());//这第一种接收 获取std::string 再转c_str
            DHPacketHeadEx* packetEx = (DHPacketHeadEx*)(byteArray.data());//这第二种支持获取data 得到char*

            switch(packetEx->packetType)
            {

            case enPacketType::PACKET_HEART_BEAT:
                {
                    QString info = "收到心跳包";
                    contentListWidget->addItem(info);
                    qDebug()<<"199 收到心跳包";
                }
                break;
            case enPacketType::PACKET_CONTENT:
                {
                    char* readContent = new char[packetEx->len];
                    memcpy(readContent,(char*)packetEx->pValue,packetEx->len);

                    QString info(readContent);
                    contentListWidget->addItem(info);
                }
            case enPacketType::PACKET_BIG_CONTENT:
            {
                char* readContent = new char[packetEx->len+1];
                memcpy(readContent,(char*)packetEx->pValue,packetEx->len);

                QString info(readContent);
                contentListWidget->addItem(info);
            }

                break;
            }

             QDateTime nowTime = QDateTime::currentDateTime();
            lastReceivePacketTime = nowTime;

            continue;
        }

``

附一个实战例子
在这里插入图片描述

后面附上:
QByteArray字节数组于QTcpSocket传输之常用操作函数,标识长度与根据长度读取

向要传输的QByteArray对象的起始位置加入特定长度的字节用于表示数据长度,在接收端的第一个readAll()中读取到这个长度,并根据这个长度读取剩余的包,现把用到的函数整理如下:

1.向字节数组的起始位置拼接另一个字节数组,返回新数组

QByteArray &QByteArray::prepend(const QByteArray &ba)

2.读取字节数组起始位置len个字节,返回读取的数组

QByteArray QByteArray::left(int len) const

3.从pos位置开始的len长度的字节替换成after(如果要删除,则替换成’\0’即可)

QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)

4.返回字节数组的长度

int QByteArray::length() const

5.将字节数组转化成int

int QByteArray::toInt(bool *ok = Q_NULLPTR, int base = 10) const

QTcpSocket 发送数据的几种方法

1、QTcpSocket 继承于QAbstractSocket继承于QIODevice

2、QTcpSocket 提供的几种接收和发送数据方法

write ( const char *, qint64 ) : qint64
write ( const char * ) : qint64
write ( const QByteArray & ) : qint64
writeData ( const char *, qint64 ) : qint64
read ( char * data, qint64 maxSize ): qint64
read ( qint64 maxSize ):QByteArray
readAll ():QByteArray
readLine ( char * data, qint64 maxSize ):qint64
readLine ( qint64 maxSize = 0 ):QByteArray

3、例子1 write ( const QByteArray & ) : qint64

Cpp代码 收藏代码
//用于暂存要发送的数据
QByteArray block;
//使用数据流写入数据
QDataStream out(&block,QIODevice::ReadWrite);
//设置数据流的版本,客户端和服务器端使用的版本要相同
out.setVersion(QDataStream::Qt_4_6);

//设置发送长度初始值为0
out << (quint16) 0;
//设置发送内容
out<<hash;

//回到字节流起始位置
out.device()->seek(0);
//重置字节流长度
out << (quint16) (block.size()-sizeof(quint16));

//往套接字缓存中写入数据,并发送
tcpSocket->write(block);

3、例子2 write ( const char *, qint64 ) : qint64

Cpp代码 收藏代码
QString *a=new QString;
tcpSocket->write(a,a->length());
4、例子3 数据流直接使用QIODevice

Cpp代码 收藏代码
QDataStream in(tcpSocket);
in<< quint16(0xFFFF); //此时QIODevice加载了此数据,而且直接发送出去

quint16 length = 0;
QDataStream out(tcpSocket);//如果此时tcpSocket直接有数据发送过来
out >> length;//length获得第一个整型值,并在tcpSocket中清空该数据

附:
QTcpSocket 提供的几种接收和发送数据方法:

write ( const char *, qint64 ) : qint64
write ( const char * ) : qint64
write ( const QByteArray & ) : qint64
writeData ( const char *, qint64 ) : qint64
read ( char * data, qint64 maxSize ): qint64
read ( qint64 maxSize ):QByteArray
readAll ():QByteArray
readLine ( char * data, qint64 maxSize ):qint64
readLine ( qint64 maxSize = 0 ):QByteArray

发送数据的示例代码:
1)write ( const QByteArray & ) : qint64
//用于暂存要发送的数据
QByteArray block;
//使用数据流写入数据
QDataStream out(&block,QIODevice::ReadWrite);
//设置数据流的版本,客户端和服务器端使用的版本要相同
out.setVersion(QDataStream::Qt_DefaultCompiledVersion);

//设置发送长度初始值为0
out << (quint16) 0;
//设置发送内容
out<<"hello, mike";

//回到字节流起始位置
out.device()->seek(0);
//重置字节流长度
out << (quint16) (block.size()-sizeof(quint16));

//往套接字缓存中写入数据,并发送
tcpSocket->write(block);

2)write ( const char *, qint64 ) : qint64
QString str = “hello, mike”;
tcpSocket->write(a, a.length());

3)数据流直接使用 QIODevice
QDataStream in(tcpSocket);
in<< quint16(0xFFFF); //此时QIODevice加载了此数据,而且直接发送出去

quint16 length = 0;
QDataStream out(tcpSocket);//如果此时tcpSocket直接有数据发送过来
out >> length;//length获得第一个整型值,并在tcpSocket中清空该数据
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt发送端用自定义结构体发送,接收端QByteArray接收 的相关文章

  • 接口文档参考示例

    接口文档参考示例 用户登录 POST api login 接口说明 登录成功后 会生成或更新用户令牌 token 使用帮助 测试数据库中预设了四个可供使用的账号 如下表所示 Untitled 请求参数 Untitled 响应信息 登录成功
  • 湖南株洲三维扫描检测CNC机加工零件截面检测弧度测量-CASAIM中科广电

    自工业时代开始以来 机械加工及零部件产业已经涵盖了各大电器零部件 汽车零部件 建筑机械零部件 航空航天零部件 海洋工程零部件等领域 涉及多种机械机床及工具仪器的制造 零件在加工过程中 受制于加工工艺等各方面的因素 难免会产生加工误差 会直接
  • Ubuntu系统中使用VSCode(Visual Studio Code)

    一 软件下载安装 去官网下载文件 https code visualstudio com docs dv linux64 也可以用ubuntu自带的软件商店下载 本帖就采用这种方法 案例采用ubuntu16 04 操作如下图 首先单击APP

随机推荐

  • maven 项目 junit步骤。

    pom xml添加对应的jar包
  • 自动化测试的转行

    什么是自动化测 做测试好几年了 真正学习和实践自动化测试一年 自我感觉这一个年中收获许多 一直想动笔写一篇文章分享自动化测试实践中的一些经验 终于决定花点时间来做这件事儿 首先理清自动化测试的概念 广义上来讲 自动化包括一切通过工具 程序
  • CSS——层级

    层级问题 选中的盒子显示的效果并不完整 右边的边框并没有显示红色 原因是其右边的盒子压了它的边框
  • Flink CDC 详述实时数据湖

    在构建实时数仓的过程中 如何快速 正确的同步业务数据是最先面临的问题 本文主要讨论一下如何使用实时处理引擎Flink和数据湖Apache Iceberg两种技术 来解决业务数据实时入湖相关的问题 01 Flink CDC介绍 CDC全称是C
  • Mac 开发 Tang Nano FPGA 指南(使用终端和使用 VS Code 和插件,适用所有 Gowin FPGA)

    最近收到了一个 Tang nano 9K FPGA开发板 就想借此机会研究一下 官方文档里介绍如果想使用高云的 FPGA 就需要使用 GOWIN IDE 但是需要申请 license 提交一堆资料 我是别人送的就不太方便让别人弄 加上 ID
  • 一,凸包---3,极边

    极边就是组成凸包的边的集合 时间复杂度是o n3 比判断极点快 时间复杂度O n4 快 为什么呢 试想 不论极边也好 极点也好 判断的依据是三角形的方向 无论是海伦公式 还是向量叉乘 极边是需要三个点组成一个三角形 是一个三重循环 即可用t
  • 六.安装harbor

    1 下载 harbor offline installer v1 9 3 链接 https pan baidu com s 1dTCy2KPqRhYKxTyE7vlrPg 提取码 6666 需要安装docker compose 2 修改配置
  • Java基础之异常

    文章目录 前言 一 初识异常 二 异常的体系结构 三 异常的分类 四 异常的处理 1 throw 异常抛出 2 throws 异常声明 3 try catch 捕获处理 4 finally 5 try catch finally与retur
  • Hugo themes Doit 合并 tags , categories 为检索页

    Hugo themes Doit 合并 tags categories 为检索页 原文 总觉得 tags categories 等页面可以合并成为一页 这样检索起来更方便一些 成果 https www ftls xyz retrieval
  • 编译程序和解释程序有什么区别?

    1 编译程序和解释程序的区别 编译型是使用编译器编译后生成计算机硬件可直接执行的指令 解释型是在运行时才由解释器逐语句去执行 编译型代表 C C C Java 解释型代表 html javascript 区别有很多 说说常见的几个 编译型语
  • MATLAB bp神经网络预测代码

    清除变量 清楚变量 claer clc 导入数据 变量个数较少可以自己输入变量 变量数目较大时建议采用读取Excel并保存成 mat的方法来导入数据 读取 m数据 以data mat为例 load data mat load data1 m
  • React路由

    安装 npm i react router dom S 导入 import BrowserRouter as Router Route Link from react router dom HashRouter与BrowserRouter
  • iOS基础教程-SQLite数据库操作(二简单实例学生信息增删改查数据库操作)

    学生名单管理界面实现数据库的增删改操作 关于UI部分 我们使用storyboard简单完成 在上一篇文章中有详细的描述iOS基础教程 SQLite数据库操作 一 StoryBoard操作 SQLite操作前准备工作 本篇结束以后 就可以完成
  • webpack设置分包

    Webpack中设置分包 code splitting 是一种优化技术 它允许将你的代码分割成多个小块 以便在不同的页面或情境中按需加载 这可以显著减小初始加载的资源大小 提高网页性能 Webpack提供了几种方式来设置分包 其中最常见的是
  • 搞懂 API ,地图 API 制作方法分享

    地图 API 是一种基于 Web 开发的应用程序编程接口 可以用于创建和展示地图及地理信息 以下是一些地图 API 制作的方法 选择地图 API 平台 目前市场上有很多地图 API 平台供选择 比如 Google Maps API 百度地图
  • WorkTool企微机器人自动接收图片回传(方案三)

    自动接收图片并上传到服务器 仅适用企业微信应用 前言 WorkTool企微机器人可以接收客户群的消息 但接收图片一直是个问题 前面也介绍过两种图片接收方案 但都会影响运行效率 并且不能达到100 的图片接收率 实测95 本方案三是通过企微官
  • 2023年测试之路,从功能测试进阶测试开发工程师,突破内卷...

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • QT5.9.6和VS2015的配置使用

    要做界面但是MFC实在是 所以果断尝试QT实现界面化 QT5 9 6 VS2015 opencv2 4 13 所用软件 QT5 9 6 VS2015 参考地址 Qt5 7 VS2015 环境搭建https blog csdn net lia
  • kafka常用命令汇总

    新建topic bin kafka topics sh zookeeper localhost 2181 create replication factor 1 partitions 1 topic test service 删除topic
  • Qt发送端用自定义结构体发送,接收端QByteArray接收

    Qt TCP UDP 一端用自定义结构体发送消息 一端用QByteArray接收消息 用自定义结构体发送消息 void TcpServer timeOut QDateTime nowTime QDateTime currentDateTim