当前位置: 首页 > news >正文

QT中,对于大小端UDP网络发送的demo,帧头帧尾

简单demo:

发送端:

#include <QUdpSocket>
#include <QtEndian>#pragma pack(1)
struct Test
{unsigned char   t1:1;unsigned char   t2:2;unsigned char   t3:3;unsigned char   t4:2;quint8    a = 1;quint16   b = 2;quint16   c = 3;//double    b = 2;quint8    d = 4;quint8    e = 1;
};
#pragma pack(pop)int main(int argc, char *argv[])
{QApplication app(argc, argv);QByteArray temp_byte_array;Test test;test.b = qToBigEndian(test.b);test.c = qToBigEndian(test.c);test.b = qToBigEndian(test.b);test.t1 = 0x1;test.t2 = 0x2;test.t3 = 0x3;test.t4 = 0x2;QUdpSocket *m_pUdpSocket = new QUdpSocket();m_pUdpSocket->bind(QHostAddress("127.0.0.1"),8002);QByteArray frame = QByteArray((char *)&test, sizeof(Test));m_pUdpSocket->writeDatagram(frame, QHostAddress("127.0.0.1"), 8001);return 0;
}

接收:

#include <QUdpSocket>
#include <QtEndian>#pragma pack(1)
struct Test
{unsigned char   t1:1;unsigned char   t2:2;unsigned char   t3:3;unsigned char   t4:2;quint8    a = 0x1;quint16   b = 0x2;quint16   c = 0x3;//double    b = 2;quint8    d = 0x4;quint8    e = 0x1;
};
#pragma pack(pop)int main(int argc, char *argv[])
{QApplication app(argc, argv);QUdpSocket *m_pUdpSocket = new QUdpSocket();m_pUdpSocket->bind(QHostAddress("127.0.0.1"),8001);QObject::connect(m_pUdpSocket,&QUdpSocket::readyRead,[=](){QByteArray frame;frame.resize(m_pUdpSocket->pendingDatagramSize());// 接收数据报,将其存放到datagram中m_pUdpSocket->readDatagram(frame.data(), frame.size());struct Test *pFrame = (struct Test *)frame.data();qDebug()<<"a:"<<pFrame->a;qDebug()<<"b:"<<pFrame->b;qDebug()<<"c:"<<pFrame->c;qDebug()<<"d:"<<pFrame->d;qDebug()<<"*****************";});return app.exec();
}

有帧头帧尾:

发送:

#include <QUdpSocket>
#include <QtEndian>// 以1字节对齐:
#pragma pack(1)
struct Test
{// 帧头 0xabcdunsigned short dataHead = 0xabcd;// 小于1字节:unsigned char   t1:1;unsigned char   t2:2;unsigned char   t3:3;unsigned char   t4:2;// 小于或者大于1字节quint8    a = 0x1;quint16   b = 0x2;quint16   c = 0x3;quint8    d = 0x4;quint8    e = 0x1;// 包尾 dcbaunsigned short dataTail = 0xdcba;
};
#pragma pack(pop)int main(int argc, char *argv[])
{QByteArray temp_byte_array;Test test;//test.b = qToBigEndian(test.b);//test.c = qToBigEndian(test.c);test.t1 = 0x1;test.t2 = 0x2;test.t3 = 0x3;test.t4 = 0x2;QUdpSocket *m_pUdpSocket = new QUdpSocket();m_pUdpSocket->bind(QHostAddress("127.0.0.1"),8002);QByteArray frame = QByteArray((char *)&test, sizeof(Test));m_pUdpSocket->writeDatagram(frame, QHostAddress("127.0.0.1"), 8001);}

接受:

#include <QUdpSocket>
#include <QtEndian>// 以1字节对齐:
#pragma pack(1)
struct Test
{// 帧头 0xabcdunsigned short dataHead = 0xabcd;// 小于1字节:unsigned char   t1:1;unsigned char   t2:2;unsigned char   t3:3;unsigned char   t4:2;// 小于或者大于1字节quint8    a = 0x1;quint16   b = 0x2;quint16   c = 0x3;quint8    d = 0x4;quint8    e = 0x1;// 包尾 dcbaunsigned short dataTail = 0xdcba;
};
#pragma pack(pop)int main(int argc, char *argv[])
{QApplication app(argc, argv);QUdpSocket *m_pUdpSocket = new QUdpSocket();m_pUdpSocket->bind(QHostAddress("127.0.0.1"),8001);QObject::connect(m_pUdpSocket,&QUdpSocket::readyRead,[=](){QByteArray frame;frame.resize(m_pUdpSocket->pendingDatagramSize());// 接收数据报,将其存放到datagram中m_pUdpSocket->readDatagram(frame.data(), frame.size());struct Test *pFrame = (struct Test *)frame.data();if(pFrame->dataHead == 0xabcd && pFrame->dataTail == 0xdcba){qDebug()<<"接收到信息*********";qDebug()<<"a:"<<pFrame->a;qDebug()<<"b:"<<pFrame->b;qDebug()<<"c:"<<pFrame->c;qDebug()<<"d:"<<pFrame->d;qDebug()<<"*****************";}});return app.exec();
}

会发现,如果不是这个帧头和帧尾,就会出问题,只有帧头帧尾正确,才可以正常解析。

注意事项:

1. 结构体前后一定要加1字节对齐,否则可能会多出很多字节,比如你们可以自己尝试不加一字节对齐,然后加入double会增加多少的字节。

2. 接收的时候,不要使用readall() 。

3. 测试的时候,发送不要使用串口调试助手等工具,哪些会出问题。

4. 大小端:很多系统默认小端,如果需要转为大端发送数据,大于1字节的数据,需要使用qToBigEndian()来转换。

http://www.lryc.cn/news/294025.html

相关文章:

  • ip网络的三类地址及其相互关系
  • 开源计算机视觉库OpenCV详细介绍
  • go消息队列RabbitMQ - 订阅模式-direct
  • PyTorch 2.2 中文官方教程(十八)
  • jenkins部署vue项目
  • 十一、C++核心编程(2)引用
  • numpy学习总结二
  • 3 编辑器(Vim)
  • C/C++ (stdio.h)标准库详解
  • 深度学习介绍
  • ywtool dhcp命令
  • ChatGPT高效提问—基础知识(LM、PLM以及LLM)
  • MongoDB复制集实战及原理分析
  • Java并发之synchronized详解
  • Flask 项目自动生成 API 文档的高效实践
  • WebChat——一个开源的聊天应用
  • 【Linux系统 01】Vim工具
  • Oracle 面试题 | 09.精选Oracle高频面试题
  • 基于Springboot的校园失物招领网站(有报告)。Javaee项目,springboot项目。
  • WPF布局面板
  • 灵活应对:策略模式在软件设计中的应用
  • eosio.token 智能合约介绍
  • 3D 转换
  • AI智能语音机器人安装方法
  • Python 潮流周刊#38:Django + Next.js 构建全栈项目
  • Jenkins升级后,构建任务配置界面重复错位
  • Python基础学习 -07 运算符
  • Nim游戏
  • Pytorch: torch.linspace等间隔数值函数
  • 【C++】案例:数列求和 与 条件筛选