基于Qt的UDP协议实现及解析数据

一、前言

UDP 是一个不可靠的,面向数据报的协议。QUdpSocket 类可以用来发送和接收UDP数据报(datagram)。

最常用的使用方式是使用bind()去绑定地址和端口号,然后使用writeDatagram()和readDatagram()去传输数据。

这个socket对象每次往网络中发送报文都会发出bytesWritten()信号。如果你只是想用QUdpSocket发送报文,就不需要调用bind().

当报文到达的时候会发readyRead()信号,在这种情况下,hasPendingDatagrams()会返回true.调用 pendingDatagramSize()方法获取报文的长度。最后调用readDatagram()读取。

二、QUDPSocekt

下面的实例WeatherServery应用程序模拟气象气球的功能,每2秒就发送一个包含当前天气情况的UDP数据报。

#ifndef WEATHERBALLOON_H
#define WEATHERBALLOON_H

#include <QWidget>
#include <QPushButton>
#include <QtNetwork/QUdpSocket>
#include <QTimer>
#include <QDateTime>
namespace Ui {
    class weatherBalloon;
}

class weatherBalloon : public QWidget
{
    Q_OBJECT

public:
    explicit weatherBalloon(QWidget *parent = 0);
    ~weatherBalloon();

private slots:
    //处理报文
    void processPendingDatagrams();
    //发送报文
    void sendDatagram();
private:
    Ui::weatherBalloon *ui;
    QUdpSocket udpSocket;
    QTimer timer; 
    double temperature;//温度
    double humidity;//湿度
    double altitude;//高度
};

#endif // WEATHERBALLOON_H

WeatherServer的实现

#include "weatherballoon.h"
#include "ui_weatherballoon.h"

weatherBalloon::weatherBalloon(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::weatherBalloon)
{
    //绑定Socket到指定地址和端口号
    udpSocket.bind(5824);

    ui->setupUi(this);
    connect(ui->btn_close,SIGNAL(clicked()),this,SLOT(close()));
    connect(&timer,SIGNAL(timeout()),this,SLOT(sendDatagram()));
    connect(&udpSocket,SIGNAL(readyRead()),this,SLOT(processPendingDatagrams()));

    timer.start(2*1000);
    temperature = 10.2;
    humidity   = 5.4;
    altitude   = 100.0;
    setWindowTitle(tr("Weather Balloon"));
}

weatherBalloon::~weatherBalloon()
{
    delete ui;
}

//发送报文
void weatherBalloon::sendDatagram(){
    QByteArray datagram;
    QDataStream out(&datagram,QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_8);
    out<<QDateTime::currentDateTime()<<temperature<<humidity<<altitude;
    qDebug()<<QDateTime::currentDateTime();
    QHostAddress address;
    address.setAddress("127.0.0.1");
    udpSocket.writeDatagram(datagram,address,5824);
}

//处理报文
void weatherBalloon::processPendingDatagrams(){
   QByteArray datagram;
   do{
       datagram.resize(udpSocket.pendingDatagramSize());
       udpSocket.readDatagram(datagram.data(),datagram.size());
   }while(udpSocket.hasPendingDatagrams());
   QDateTime dateTime;
   double temperature;
   double humidity;
   double altitude;
   qDebug()<<"recive date ";
   QDataStream in(&datagram,QIODevice::ReadOnly);
   in.setVersion(QDataStream::Qt_4_8);
   in>>dateTime>>temperature>>humidity>>altitude;


   ui->lineEdit_Date->setText(dateTime.date().toString());
   ui->lineEdit_CurrentTime->setText(dateTime.time().toString());
   ui->lineEdit_Temperature->setText(tr("%1 °c").arg(temperature));
   ui->lineEdit_Humidity->setText(tr("%1%").arg(humidity));
   ui->lineEdit_Alt->setText(tr("%1 m").arg(altitude));

}

三、发送结构体及解析其数据

发送端:
头文件中建立结构体state:

#pragma pack(1) //此时编译器字节对齐方式为1byte,且为不进栈模式[#pragma push(pack,1)]
struct state{
    int order;
    int speed;
    double longitude;
    double latitude;
};

#pragma pack()



实现cpp文件:

state data;
data.order=1;
data.speed=50;
data.longitude=120.34;
data.latitude=36.89;
udpSocket->writeDatagram((char*)&data,sizeof(data),QQHostAddress::Broadcast,port);



接收端
在头文件中建立结构体,与发送端一样。

接收cpp文件:

state datagram;
udpSocket->readDatagram((char*)&datagram,sizeof(datagram));



然后就可以读取结构体数据,像这样:

int Order=datagram.order;
int Speed=datagram.speed;
double Longitude=datagram.longitude;
double Latitude=datagram.latitude;


 

 

 


参考资料:

C++ GUI Qt5 编程

Qt 帮助文档中关于QUdpSocket

  • 6
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt中使用UDP通信协议进行数据传输时,首先要创建一个QUdpSocket对象来实现数据的接收和发送。以下是一个简单的上位机解析数据代码示例: 使用QUdpSocket对象来接收数据: 1. 创建一个QUdpSocket对象:QUdpSocket *udpSocket = new QUdpSocket(this); 2. 绑定接收数据的IP地址和端口:udpSocket->bind(QHostAddress("127.0.0.1"), 8080); 3. 创建一个槽函数来接收数据:void onDataReceived(); 在槽函数中解析数据: void onDataReceived() { QByteArray datagram; // 用于存储接收到数据 while (udpSocket->hasPendingDatagrams()) { // 判断是否有待接收的数据 datagram.resize(udpSocket->pendingDatagramSize()); // 调整datagram的大小以适应接收的数据 udpSocket->readDatagram(datagram.data(), datagram.size()); // 读取接收到数据 } // 在此处对接收到数据进行解析 // 解析方法根据实际的通信协议而定 // 可以使用QByteArray的相关方法和函数来解析数据 qDebug() << "Received datagram: " << datagram; // 打印接收到数据 } 在主函数中连接信号和槽: QObject::connect(udpSocket, SIGNAL(readyRead()), this, SLOT(onDataReceived())); // 将readyRead信号与onDataReceived槽函数连接起来 通过上述代码,可以实现基于QtUDP上位机解析数据,具体的解析方法需要根据实际的通信协议来确定。注意,在实际应用中,还需要对异常情况进行处理,比如网络异常、数据丢失等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值