使用QT多线程UDP发送结构体。

首先是服务端,在构造函数中实例化UDP,并且创建成员函数进行发送,通过QTIMER类以10HZ的频率发送;

//udpserver.h
#ifndef UDPSERVER_H
#define UDPSERVER_H
#include <QUdpSocket>
#include <QHostAddress>
#include <QTimer>
#pragma pack(push, 1) // 设置字节对齐为1字节
struct MyStruct {
    quint16 checksum;
    quint16 data1;
    quint32 data2;
};
#pragma pack(pop) // 恢复字节对齐设置
class MyUDP : public QObject
{
    Q_OBJECT

public:
    explicit MyUDP(QObject *parent = 0);
private:
    QUdpSocket *socket;
    QTimer *timer;
public slots:
    void SayGps();
};
#endif // UDPSERVER_H
//udpserver.cpp
#include "udpserver.h"

MyUDP::MyUDP(QObject *parent) :
    QObject(parent)
{
    socket = new QUdpSocket(this);
    timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&MyUDP::SayGps);//通过信号与槽触发
    timer->start(100);//100ms发送一次
}

void MyUDP::SayGps()     
{
    // 准备要发送的结构体数据
    MyStruct myStruct;
    myStruct.checksum = 0x1234; // 设置结构体第一个参数的检验位
    myStruct.data1 = 1234;
    myStruct.data2 = 567890;
    socket->writeDatagram(reinterpret_cast<const char *>(&myStruct), sizeof(MyStruct),
                            QHostAddress::LocalHost, 1234);

}

//main.cpp
#include "udpserver.h"
#include <QCoreApplication>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    MyUDP server;
    return a.exec();
}

客户端接收代码,将客户端的一个类放入子线程。如需增加线程,接收其他端口的数据,可新实例化一个新的MyUDP类,并且修改端口号即可;

//udpclient.h
#ifndef UDPCLIENT_H
#define UDPCLIENT_H
#include <QUdpSocket>
#include <QHostAddress>

#pragma pack(push, 1) // 设置字节对齐为1字节
struct MyStruct {
    quint16 checksum;
    quint16 data1;
    quint32 data2;
};
#pragma pack(pop) // 恢复字节对齐设置

class MyUDP : public QObject
{
    Q_OBJECT

public:
    explicit MyUDP(QObject *parent = 0);

private:
    QUdpSocket *socket;

public slots:
    void receiveDatagram();
};
#endif // UDPCLIENT_H
//udpclient.cpp
#ifndef UDPCLIENT_CPP
#define UDPCLIENT_CPP
#include "udpclient.h"

MyUDP::MyUDP(QObject *parent) :
    QObject(parent)
{
    socket = new QUdpSocket(this);
    bool result = socket->bind(1234);
}

void MyUDP::receiveDatagram()
{
    QByteArray buffer;
    buffer.resize(socket->pendingDatagramSize());
    socket->readDatagram(buffer.data(), buffer.size());
    MyStruct receivedStruct;
    memcpy(&receivedStruct, buffer.constData(), sizeof(MyStruct));
    if (receivedStruct.checksum == 0x1234) {
        qDebug() << "Received data1:" << receivedStruct.data1;
        qDebug() << "Received data2:" << receivedStruct.data2;
    } else {
        qDebug() << "Checksum mismatch, discarding received data.";
    }

}
#endif // UDPCLIENT_CPP


//main.cpp
#include <QCoreApplication>
#include <QObject>
#include <QTimer>
#include "udpclient.h"
#include <qthread.h>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyUDP myUDP;
    QThread thread_0;// 创建一个线程
    // 将myUDP对象移动到子线程中
    myUDP.moveToThread(&thread_0);
    // 连接Worker对象的sendDatagram()槽和QTimer对象的timeout()信号
    QTimer timer;
    QObject::connect(&timer, &QTimer::timeout, &myUDP, &MyUDP::receiveDatagram);
    // 启动子线程
    thread_0.start();
    // 启动定时器
    timer.start(100);

    return a.exec();
}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值