文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Qt实现UDP多线程数据处理及发送的简单实例

2024-04-02 19:55

关注

逻辑与运行

程序逻辑图如下:

接收端运行截图如下:

客户端接收数据如下:

客户端用的是串口调试工具:

源码

程序结构如下:

源码如下:

data.h


#ifndef DATA_H
#define DATA_H
 
#include <QObject>
#include <QHostAddress>
#include <QString>
#include <QDebug>
 
#define SenderListWidget 0
#define ReceviListWidget 1
 
class PeerIP{
public:
    quint32 IPv4Address;
    quint16 port;
 
    PeerIP(const quint32 Ip, const quint16 por){
 
        IPv4Address = Ip;
        port = por;
    }
 
    friend QDebug operator << (QDebug os, PeerIP peerIP){
 
        os << "(" << peerIP.IPv4Address << ", " << peerIP.port
           << ")";
 
        return os;
    }
};
 
 
class UDPMsg{
 
public:
    virtual QString backFunction(const PeerIP *peerIP){
 
        Q_UNUSED(peerIP)
        return "";
    }
 
protected:
    UDPMsg(){}
    virtual ~UDPMsg(){}
};
 
class UDPMsgReciver:public UDPMsg{
 
public:
    QString backFunction(const PeerIP *peerIP){
 
        QHostAddress address(peerIP->IPv4Address);
        QString msg = "接收到P:" + address.toString() + " 端口:" + QString::number(peerIP->port) + "发来数据包, 正在处理数据";
        return msg;
    }
};
 
class UDPMsgSender:public UDPMsg{
 
public:
    QString backFunction(const PeerIP *peerIP){
 
        QHostAddress address(peerIP->IPv4Address);
        QString msg = "已发送到IP:" + address.toString() + " 端口:" + QString::number(peerIP->port) + "UDP数据包,准备发送数据";
        return msg;
    }
};
 
#endif // DATA_H

msgqueue.h


#ifndef MSGQUEUE_H
#define MSGQUEUE_H
 
#include <QThread>
#include <QList>
#include <QWidget>
 
class PeerIP;
class UDPMsg;
class Widget;
 
 
class MsgQueue: public QThread
{
public:
    enum MsgType{RecvQueue, SendQueue};
    MsgQueue(Widget *widget, MsgType type);
    ~MsgQueue();
 
    void appendPeerIP(const quint32 ipV4, const quint16 port);
    void stop();
 
protected:
    void run();
 
private:
    QList<PeerIP*> m_list;
    MsgType m_type;
    bool m_canExit;
    UDPMsg *m_udpMsg;
    Widget *m_widget;
};
 
#endif // MSGQUEUE_H

widget.h


#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QList>
 
QT_BEGIN_HEADER
class QUdpSocket;
QT_END_NAMESPACE
 
class PeerIP;
class MsgQueue;
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
 
    void insertMsgInList(const int Type, const QString msg);
    void senderMsg(quint32 ipV4, quint16 port);
 
 
protected:
    void canAppendInList(const quint32 ipV4, const quint16 port);
    void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;
 
protected slots:
    void readPendingDatagrams();
 
private:
    Ui::Widget *ui;
    QUdpSocket *m_udpSocket;
    QList<PeerIP*> m_peerIP;
 
    MsgQueue *m_sender;
    MsgQueue *m_receiv;
};
 
#endif // WIDGET_H

main.cpp


#include "widget.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
 
    return a.exec();
}

msgqueue.cpp


#include "msgqueue.h"
#include "data.h"
#include "widget.h"
#include <QDebug>
 
MsgQueue::MsgQueue(Widget *widget, MsgType type):
    m_canExit(false)
{
    if(type == RecvQueue){
 
        m_udpMsg = new UDPMsgSender;
    }
    else{
 
        m_udpMsg = new UDPMsgReciver;
    }
    m_widget = widget;
    m_type = type;
    start();
}
 
MsgQueue::~MsgQueue()
{
    for(int i = 0; i < m_list.size(); i++){
 
        delete m_list[i];
    }
}
 
void MsgQueue::appendPeerIP(const quint32 ipV4, const quint16 port)
{
    PeerIP *peerIp = new PeerIP(ipV4, port);
    m_list.append(peerIp);
}
 
void MsgQueue::stop()
{
    m_canExit = true;
}
 
void MsgQueue::run()
{
    while(!m_canExit){
 
        for(int i = 0; i < m_list.size(); i++){
 
            QString msg = m_udpMsg->backFunction(m_list[i]);
            m_widget->insertMsgInList(m_type, msg);
 
            if(m_type == RecvQueue){
 
                //这里可以写后端处理
            }
            else{
 
                m_widget->senderMsg(m_list[i]->IPv4Address, m_list[i]->port);
            }
        }
        msleep(1000);
    }
}

widget.cpp


#include "widget.h"
#include "ui_widget.h"
#include "data.h"
#include "msgqueue.h"
#include <QUdpSocket>
#include <QNetworkDatagram>
#include <QHostAddress>
#include <QDebug>
#include <QEventLoop>
#include <QTimer>
 
 
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
    this->setWindowTitle("CSDN IT1995");
 
    m_udpSocket = new QUdpSocket(this);
 
    if(!m_udpSocket->bind(7755)){
 
        qDebug() << "bind failed! The assert will be triggred!";
        Q_ASSERT(!"bind failed!");
    }
 
    m_sender = new MsgQueue(this, MsgQueue::SendQueue);
    m_receiv = new MsgQueue(this, MsgQueue::RecvQueue);
 
    connect(m_udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
}
 
Widget::~Widget()
{
    delete ui;
    delete m_sender;
    delete m_receiv;
    for(int i = 0; i < m_peerIP.size(); i++){
 
        delete m_peerIP[i];
    }
}
 
void Widget::insertMsgInList(const int Type, const QString msg)
{
    if(Type == SenderListWidget){
 
        ui->senderListWidget->insertItem(0, msg);
    }
    else{
 
        ui->receiverListWidget->insertItem(0, msg);
    }
}
 
void Widget::senderMsg(quint32 ipV4, quint16 port)
{
    QHostAddress address(ipV4);
    m_udpSocket->writeDatagram(QByteArray("I am fine, fuck you!"), address, port);
}
 
void Widget::canAppendInList(const quint32 ipV4, const quint16 port)
{
    for(int i = 0; i < m_peerIP.size(); i++){
 
        if(m_peerIP[i]->IPv4Address == ipV4 && m_peerIP[i]->port == port){
 
            qDebug() << "client in list";
            return;
        }
    }
    PeerIP *peerIP = new PeerIP(ipV4, port);
    m_peerIP.append(peerIP);
    m_sender->appendPeerIP(ipV4, port);
    m_receiv->appendPeerIP(ipV4, port);
}
 
void Widget::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event)
    m_sender->stop();
    m_receiv->stop();
 
    QEventLoop loop;
    QTimer::singleShot(1000, &loop, SLOT(quit()));
    loop.exec();
    this->close();
}
 
void Widget::readPendingDatagrams()
{
    while(m_udpSocket->hasPendingDatagrams()){
 
 
        QHostAddress srcAddress;
        quint16 nSrcPort;
        QByteArray datagram;
        datagram.resize(m_udpSocket->pendingDatagramSize());
        m_udpSocket->readDatagram(datagram.data(), datagram.size(), &srcAddress, &nSrcPort);;
        canAppendInList(srcAddress.toIPv4Address(), nSrcPort);
    }
}

到此这篇关于Qt实现UDP多线程数据处理及发送的简单实例的文章就介绍到这了,更多相关Qt UDP多线程发送内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯