Qt工作笔记-UDP多线程数据处理及发送(简单实例)
生活随笔
收集整理的這篇文章主要介紹了
Qt工作笔记-UDP多线程数据处理及发送(简单实例)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
目錄
?
邏輯與運行
源碼
邏輯與運行
程序邏輯圖如下:
?
接收端運行截圖如下:
客戶端接收數(shù)據(jù)如下:
客戶端用的是串口調試工具:
?
源碼
程序結構如下:
源碼如下:
data.h
#ifndef DATA_H #define DATA_H#include <QObject> #include <QHostAddress> #include <QString> #include <QDebug>#define SenderListWidget 0 #define ReceviListWidget 1class 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) + "發(fā)來數(shù)據(jù)包, 正在處理數(shù)據(jù)";return msg;} };class UDPMsgSender:public UDPMsg{public:QString backFunction(const PeerIP *peerIP){QHostAddress address(peerIP->IPv4Address);QString msg = "已發(fā)送到IP:" + address.toString() + " 端口:" + QString::number(peerIP->port) + "UDP數(shù)據(jù)包,準備發(fā)送數(shù)據(jù)";return msg;} };#endif // DATA_Hmsgqueue.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_Hwidget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QList>QT_BEGIN_HEADER class QUdpSocket; QT_END_NAMESPACEclass PeerIP; class MsgQueue;namespace Ui { class Widget; }class Widget : public QWidget {Q_OBJECTpublic: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_Hmain.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文档阅读笔记-Advanced Si
- 下一篇: 谁动了你的主机-Windows“唤醒”和