QT5实现UDP通信的示例代码

 更新时间:2021年12月14日 16:11:27   作者:GG_ber  
本文主要介绍了QT5实现UDP通信的示例代码,主要使用QUdpSocket类用于实现UDP通信,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

前言

该例程经过实际验证可以正常使用,只简单的使用UDP中的单播模式(一对一),其余模式将在后期逐步说明。。。。。。
所用测试系统在同一局域网,其中:
QT版本:5.12
PC端UDP模式:单播
UDP通信目标:基于STM32F4+LWIP协议的以太网接口

一、UDP通信概述

UDP是轻量的、不可靠的、面向数据报、无连接的协议,它可以用于对可靠性要求不高的场合,和TCP通信不同,两个程序之间进行UDP通信无需预先建立持久的socket连接,UDP每次发送数据报都需要指定目标地址和端口。
QUdpSocket类用于实现UDP通信。发送数据报使用writeDatagram()函数,数据报的长度一般小于512字节,每个数据报包含发送者和接收者的IP地址和端口等信息;接收数据报要先用bind()函数绑定一个端口,当有数据传入时会触发readyRead信号,使用readDatagram()函数来读取接收到的数据。

二、UDP单播模式

本文实现的是上位机(PC)向下位机(STM32)发送信息,STM32接收到信息之后回立刻返回一帧信息,上位机接收到信息之后,解析命令得到下位机的IP地址和端口号,并同信息内容一同打印。
先在QT的.pro文件中添加QT += network。

1.接收数据

要实现UDP数据的接收,必须先用bind()函数绑定本机的一个端口,用于监听传入的数据报,解除绑定则使用abort()函数。绑定端口之后,当上位机接收到数据就会触发QUdpSocket类中的readyRead()信号,因此将该信号通过槽函数连接到UDPSocketReadyRead()函数处理接收到的数据。

/*
*   接收数据
*/
void MainWindow::UDPSocketReadyRead()
{

    while(Myudpsocket->hasPendingDatagrams())
    {
        QByteArray Recivedata;
        Recivedata.resize(Myudpsocket->pendingDatagramSize());
        QHostAddress peerAddr;
        quint16 peerPort;
        Myudpsocket->readDatagram(Recivedata.data(), Recivedata.size(), &peerAddr, &peerPort);
        QString str = Recivedata.data();
        QString peer = "[From" + peerAddr.toString() + ":" + QString::number(peerPort) +"]";
        ui->textEdit_recive->setText(peer+str);
    }
}

2.发送数据

使用writeDatagram()函数向下位机发送消息时,需要指定目标地址和端口。QUdpSocket发送的数据报是QByteArray类型,长度一般不超过512字节。

/*
*   发送数据
*/
void MainWindow::on_pushButton_UDP_send_clicked()
{
    QHostAddress GoalADDr(QString(ui->comboBox_goalIP->currentText()));
    quint16 GoalPort = ui->spinBox_goalport->value();
    QString sendstr = ui ->textEdit_send->toPlainText();
    QByteArray str = sendstr.toUtf8();
    Myudpsocket->writeDatagram(str, GoalADDr, GoalPort);
//    ui->label_information->setText("send ok!");
}

总结

以下代码已经经过实际的验证,可正常使用!!!

代码h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtNetwork/QUdpSocket>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QNetworkInterface>
#include <QtNetwork/QNetworkAddressEntry>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void UDPSocketReadyRead();

    void on_pushButton_UDP_send_clicked();

    void on_pushButton_UDP_bind_clicked();

private:
    Ui::MainWindow *ui;

    QString GetlocalIP();

    QUdpSocket *Myudpsocket;

};

#endif // MAINWINDOW_H

代码c文件

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /********获取本机IP地址**********/
    QString localIP = GetlocalIP();
    this->setWindowTitle("---本机IP:"+localIP);
    ui->comboBox_localIP->addItem(localIP);

    /********本机IP设置**********/
    Myudpsocket = new QUdpSocket(this);
    connect(Myudpsocket, &QUdpSocket::readyRead, this, &MainWindow::UDPSocketReadyRead);

}

MainWindow::~MainWindow()
{
    Myudpsocket->abort();          //解除绑定
    delete ui;
}

/*
*   获取本机IP地址
*/
QString MainWindow::GetlocalIP()
{
    QString strIpAddress;
    QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
    // 获取第一个本主机的IPv4地址
    int nListSize = ipAddressesList.size();
    for (int i = 0; i < nListSize; ++i)
    {
           if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
               ipAddressesList.at(i).toIPv4Address()) {
               strIpAddress = ipAddressesList.at(i).toString();
               break;
           }
     }
     // 如果没有找到,则以本地IP地址为IP
     if (strIpAddress.isEmpty())
        strIpAddress = QHostAddress(QHostAddress::LocalHost).toString();
     return strIpAddress;
}

/*
*   接收数据
*/
void MainWindow::UDPSocketReadyRead()
{

    while(Myudpsocket->hasPendingDatagrams())
    {
        QByteArray Recivedata;
        Recivedata.resize(Myudpsocket->pendingDatagramSize());
        QHostAddress peerAddr;
        quint16 peerPort;
        Myudpsocket->readDatagram(Recivedata.data(), Recivedata.size(), &peerAddr, &peerPort);
        QString str = Recivedata.data();
        QString peer = "[From" + peerAddr.toString() + ":" + QString::number(peerPort) +"]";
        ui->textEdit_recive->setText(peer+str);
    }
}

/*
*   发送数据
*/
void MainWindow::on_pushButton_UDP_send_clicked()
{
    QHostAddress GoalADDr(QString(ui->comboBox_goalIP->currentText()));
    quint16 GoalPort = ui->spinBox_goalport->value();
    QString sendstr = ui ->textEdit_send->toPlainText();
    QByteArray str = sendstr.toUtf8();
    Myudpsocket->writeDatagram(str, GoalADDr, GoalPort);
//    ui->label_information->setText("send ok!");
}

/*
*   绑定端口
*/
void MainWindow::on_pushButton_UDP_bind_clicked()
{
    quint16 port = ui->spinBox_localport->value();
    if(Myudpsocket->bind(port))
    {
        ui->label_information->setText(QString("端口号:%1 绑定成功").arg(port));
    }else {
        ui->label_information->setText(QString("端口号:%1 绑定失败").arg(port));
    }
}

到此这篇关于QT5实现UDP通信的示例代码的文章就介绍到这了,更多相关QT5 UDP通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ 递归遍历文件并计算MD5的实例代码

    C++ 递归遍历文件并计算MD5的实例代码

    在本篇文章里小编给大家整理的是一篇关于C++ 递归遍历文件并计算MD5的实例代码,有兴趣的朋友们可以学习参考下。
    2021-07-07
  • C++实现随机生成迷宫地牢

    C++实现随机生成迷宫地牢

    这篇文章主要介绍了C++实现随机生成迷宫地牢的相关资料及代码分享,推荐给大家,有需要的小伙伴可以参考下。
    2015-03-03
  • javascript 两种声明函数的方式的分析

    javascript 两种声明函数的方式的分析

    这篇文章主要介绍了javascript 两种声明函数的方式的分析的相关资料,需要的朋友可以参考下
    2017-02-02
  • QSS样式表实现界面换肤功能

    QSS样式表实现界面换肤功能

    这篇文章主要介绍了QSS样式表实现界面换肤功能,对QSS样式表进行简单介绍,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • C语言中字符串实现正序与逆序实例详解

    C语言中字符串实现正序与逆序实例详解

    这篇文章主要介绍了C语言中字符串实现倒叙实例详解的相关资料,需要的朋友可以参考下
    2017-07-07
  • C语言中的数组和指针汇编代码分析实例

    C语言中的数组和指针汇编代码分析实例

    这篇文章主要介绍了C语言中的数组和指针汇编代码分析实例,本文用一则C语言例子来得到对应的汇编代码,并一一注解每句汇编代码的含义,需要的朋友可以参考下
    2015-06-06
  • C++面试题之结构体内存对齐计算问题总结大全

    C++面试题之结构体内存对齐计算问题总结大全

    这篇文章主要给大家总结了关于C++面试题中结构体内存对齐计算问题的相关资料,文中通过示例代码介绍的非常详细,通过这些介绍的内容对大家在面试C++工作的时候,会有一定的参考帮助,需要的朋友们下面随着小编来一起学习学习吧。
    2017-08-08
  • 浅谈Qt中使用CEF的几个要点(Windows下)

    浅谈Qt中使用CEF的几个要点(Windows下)

    下面小编就为大家带来一篇浅谈Qt中使用CEF的几个要点(Windows下)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • C语言深入分析函数与宏的使用

    C语言深入分析函数与宏的使用

    C语言函数是一种函数,用来编译C语言,一般包括字符库函数,数学函数,目录函数,进程函数,诊断函数,操作函数等,宏在C语言中是一段有名称的代码片段。无论何时使用到这个宏的时候,宏的内容都会被这段代码替换掉
    2022-04-04
  • OpenSSL使用AES实现文件加解密功能

    OpenSSL使用AES实现文件加解密功能

    AES是一种对称加密算法,它是目前广泛使用的加密算法之一,意味着加密和解密使用相同的密钥,这就要求密钥的安全性非常重要,因为任何拥有密钥的人都能进行加密和解密操作,本文给大家介绍了OpenSSL如何使用AES实现文件加解密功能,需要的朋友可以参考下
    2023-11-11

最新评论