服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - Qt实现UDP多线程数据处理及发送的简单实例

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

2022-02-10 15:45IT1995 C/C++

本文主要介绍了Qt实现UDP多线程数据处理及发送的简单实例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

逻辑与运行

程序逻辑图如下:

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

接收端运行截图如下:

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

客户端接收数据如下:

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

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

 

源码

程序结构如下:

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

原文链接:https://blog.csdn.net/qq78442761/article/details/85535391

延伸 · 阅读

精彩推荐
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16