Qt工作笔记-UDP多线程数据处理及发送(简单实例)

目录

 

逻辑与运行

源码


逻辑与运行

程序逻辑图如下:

Qt工作笔记-UDP多线程数据处理及发送(简单实例)_第1张图片

 

接收端运行截图如下:

客户端接收数据如下:

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

 

源码

程序结构如下:

Qt工作笔记-UDP多线程数据处理及发送(简单实例)_第2张图片

源码如下:

data.h

#ifndef DATA_H
#define DATA_H

#include 
#include 
#include 
#include 

#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 
#include 
#include 

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 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 
#include 

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 m_peerIP;

    MsgQueue *m_sender;
    MsgQueue *m_receiv;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include 

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 

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 
#include 
#include 
#include 
#include 
#include 


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);
    }
}

 

你可能感兴趣的:(C/C++,Qt,TCP/IP)