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

逻辑与运行

程序逻辑图如下:

接收端运行截图如下:

客户端接收数据如下:

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

源码

程序结构如下:

源码如下:

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多线程发送内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解PyQt5 GUI 接收UDP数据并动态绘图的过程(多线程间信号传递)

    目录 1. Qt 的用法 2. Pycharm 设置 2.1 安装 Pyqt5 和 pyinstaller 包 2.2 Pycharm pyqt工具配置 3 UDP图形界面设计 3.1 GUI设计 3.2 将GUI文件转换为py文件 3.3 widget窗体提升,整合matplotlib的功能 3.4 GUI 设计结果 4 多线程编程UDP通讯 4.1 信号和槽函数 4.2 多线程 5 Pyinstaller 打包成exe 1. Qt 的用法   pyqt5是qt的python版本,其主要是以对

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

    逻辑与运行 程序逻辑图如下: 接收端运行截图如下: 客户端接收数据如下: 客户端用的是串口调试工具: 源码 程序结构如下: 源码如下: data.h #ifndef DATA_H #define DATA_H #include <QObject> #include <QHostAddress> #include <QString> #include <QDebug> #define SenderListWidget 0 #define ReceviListW

  • java 使用HttpURLConnection发送数据简单实例

    java 使用HttpURLConnection发送数据简单实例 每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络.请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响.如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字.JAVA使用HttpURLCon

  • java 多线程死锁详解及简单实例

    java 多线程死锁 相信有过多线程编程经验的朋友,都吃过死锁的苦.除非你不使用多线程,否则死锁的可能性会一直存在.为什么会出现死锁呢?我想原因主要有下面几个方面: (1)个人使用锁的经验差异     (2)模块使用锁的差异     (3)版本之间的差异     (4)分支之间的差异     (5)修改代码和重构代码带来的差异 不管什么原因,死锁的危机都是存在的.那么,通常出现的死锁都有哪些呢?我们可以一个一个看过来,     (1)忘记释放锁 void data_process() { Ent

  • Qt多线程实现网络发送文件功能

    本文实例为大家分享了Qt多线程实现网络发送文件功能的具体代码,供大家参考,具体内容如下 客户端给服务器发送文件,服务器进行接收文件的简单操作 1. 服务器 1. 创建QTcpServer 类的对象 QTcpServer * server = new QTcpServer(this); 2. 进行监听 bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0) 3. 通过接收

  • Qt实现UDP通信的示例代码

    目录 服务器端-单线程 客户端 测试结果-单线程 服务器端-多线程 测试结果-多线程 设想有如下场景:若干的客户端与服务器端建立连接,建立连接后,服务器端随机发送字符串给客户端,客户端打印输出.该节案例使用TCP编程. 服务器端-单线程 头文件 #pragma once // //tcp服务端-单线程处理客户端连接 #include <QAbstractSocket> #include <QObject> class QTcpServer; class SimpleTcpSocke

  • QT网络编程UDP下C/S架构广播通信(实例讲解)

    QT有封装好的UDP协议的类,QUdpSocket,里面有我们想要的函数接口.感兴趣的话,可以看看. 先搞服务端吧,写一个子类,继承QDialog类,起名为UdpServer类.头文件要引用我们上边说的QUdpSocket这个类,还有我们想要的布局的类. #ifndef UDPSERVER_H #define UDPSERVER_H #include <QDialog> #include <QLabel> #include <QLineEdit> #include &l

  • Java实现UDP多线程在线咨询

    本文实例为大家分享了Java实现UDP多线程在线咨询,供大家参考,具体内容如下 1.发送的线程 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import jav

  • Python udp网络程序实现发送、接收数据功能示例

    本文实例讲述了Python udp网络程序实现发送.接收数据功能.分享给大家供大家参考,具体如下: 1. udp网络程序-发送数据 创建一个基于udp的网络程序流程很简单,具体步骤如下: 创建客户端套接字 发送/接收数据 关闭套接字 代码如下: #coding=utf-8 from socket import * # 1. 创建udp套接字 udp_socket = socket(AF_INET, SOCK_DGRAM) # 2. 准备接收方的地址 # '192.168.1.103'表示目的ip

  • JAVA模拟多线程给多用户发送短信

    这篇文章主要介绍了JAVA模拟多线程给多用户发送短信,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码编写逻辑,假设需要给11个用户发送短信,每一个线程给两个用户发送短信,实现多线程的并发处理 创建实体user package www.it.com.test; /** * @author wangjie * @date 2019/11/20 17:10 * @description * @company 石文软件有限公司 */ public

  • Java 基于UDP协议实现消息发送

    发短信:不用连接,但需要知道对方的地址,客户端.服务端没有明确的界限,可以说没有客户端.服务端一说. 发送端 package lesson03; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * 发送端 */ public class UdpClientDemo1 { public static void main(String[] args) th

随机推荐