Qt中QUdpSocket类的简单使用详解

 更新时间:2026年01月04日 10:02:20   作者:追烽少年x  
文章介绍了QUdpSocket类的基本使用方法,包括发送端和接收端的代码实现,QUdpSocket是Qt中用于UDP通信的类,它支持无连接通信、广播和数据包的发送与接收,文章还提到了数据编码和对比TCP的简化点,感兴趣的朋友跟随小编一起看看吧

QUdpSocket类的简单使用

下面我们用一个做一个简单的例子。

一、发送端

发送端界面:

发送端代码:

.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void on_btnUnicast_clicked();
    void on_btnBoardcast_clicked();
private:
    Ui::MainWindow *ui;
    QUdpSocket* m_pSender = nullptr;
};
#endif // MAINWINDOW_H

.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_pSender = new QUdpSocket(this);
}
MainWindow::~MainWindow()
{
    delete ui;
    delete m_pSender;
}
void MainWindow::on_btnUnicast_clicked()
{
    QString strText = ui->lineEdit->text();
    if(strText.isEmpty())
        return;
    QHostAddress host("127.0.0.1");
    quint16 nPort = 8888;
    qint64 nSend = m_pSender->writeDatagram(strText.toUtf8(),host,nPort);
    if(nSend == -1)
    {
        qDebug() << "单播发送失败" << m_pSender->errorString();
    }
    else
    {
        qDebug() << "单播发送成功,字节数" << nSend;
    }
}
void MainWindow::on_btnBoardcast_clicked()
{
    QString strText = ui->lineEdit->text();
    if(strText.isEmpty())
        return;
    quint16 nPort = 8888;
    qint64 nSend = m_pSender->writeDatagram(strText.toUtf8(),QHostAddress::Broadcast,nPort);
    if(nSend == -1)
    {
        qDebug() << "广播发送失败" << m_pSender->errorString();
    }
    else
    {
        qDebug() << "广播发送成功,字节数" << nSend;
    }
}

二、接收端

接受端的界面,比较简单:

接受端代码如下:

.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
public slots:
    void ReadDatagram();
private:
    Ui::MainWindow *ui;
    QUdpSocket* m_pReceiver;
};
#endif // MAINWINDOW_H

.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_pReceiver = new QUdpSocket(this);
    quint16 listenPort = 8888;
    // 绑定端口:QHostAddress::Any 表示监听所有网卡的该端口(支持本机/局域网/外网)
    bool bBind = m_pReceiver->bind(QHostAddress::Any,listenPort);
    if(!bBind)
    {
        ui->textEdit->append("绑定端口失败:" + m_pReceiver->errorString());
    }
    else
    {
        ui->textEdit->append("已绑定端口 " + QString::number(listenPort) + ",等待接收数据...");
    }
    // 绑定接收数据信号:当有数据到达时触发readyRead()
    connect(m_pReceiver,&QUdpSocket::readyRead,this,&MainWindow::ReadDatagram);
}
MainWindow::~MainWindow()
{
    delete ui;
    delete m_pReceiver;
}
void MainWindow::ReadDatagram()
{
    // 循环读取所有待处理的数据包(可能同时有多个)
    while (m_pReceiver->hasPendingDatagrams())
    {
        QByteArray datagram;
        // 预留足够的缓冲区(根据数据包大小调整,这里设为1024)
        datagram.resize(m_pReceiver->pendingDatagramSize());
        QHostAddress senderIp; // 发送方IP
        quint16 senderPort;    // 发送方端口
        // 读取数据包,同时获取发送方的IP和端口
        qint64 readBytes = m_pReceiver->readDatagram(
            datagram.data(),
            datagram.size(),
            &senderIp,
            &senderPort
            );
        if (readBytes == -1)
        {
            ui->textEdit->append("接收失败:" + m_pReceiver->errorString());
            continue;
        }
        // 解析并显示数据
        QString recvData = QString::fromUtf8(datagram);
        QString log = QString("[%1:%2] 接收数据:%3")
                          .arg(senderIp.toString())
                          .arg(senderPort)
                          .arg(recvData);
        ui->textEdit->append(log);
    }
}

代码说明:

  1. 核心类QUdpSocket
    • 发送:writeDatagram() 直接发送数据包,无需建立连接,这是 UDP “无连接” 的核心体现;
    • 接收:绑定端口后,通过readyRead()信号监听数据,readDatagram()读取数据并获取发送方信息;
    • 广播:QHostAddress::Broadcast 是 UDP 独有的能力,TCP 无法实现。
  2. 绑定端口的参数
    • QHostAddress::Any:监听所有网卡的指定端口,支持接收来自本机、局域网其他设备的 UDP 数据;
    • 若仅监听本机,可用QHostAddress::LocalHost(127.0.0.1)。
  3. 数据编码
    • toUtf8()/fromUtf8()转换QStringQByteArray,保证跨平台编码一致性,避免中文乱码。
  4. 对比 TCP 的简化点
    • UDP 无需调用connectToHost()建立连接,也无需处理connected()/disconnected()信号;
    • 无需处理粘包:pendingDatagramSize()可获取单个数据包的大小,一次读取即可,而 TCP 需自定义协议拆包。

项目运行结果:

到此这篇关于Qt中QUdpSocket类的简单使用的文章就介绍到这了,更多相关Qt QUdpSocket类使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现bmp格式图像读写

    C++实现bmp格式图像读写

    这篇文章主要为大家详细介绍了C++实现bmp格式图像读写,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 一文搞懂C++中的四种强制类型转换

    一文搞懂C++中的四种强制类型转换

    很多朋友向小编了解C语言中怎么进行强制类型转换呢?在这小编告诉大家强制类型转换可以分为两种,一种是隐式类型转换一种是显示类型转换,下面通过示例代码给大家介绍下,需要的朋友参考下吧
    2021-07-07
  • C语言volatile关键字的作用与示例

    C语言volatile关键字的作用与示例

    这篇文章主要介绍了C语言volatile关键字的作用,volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据
    2023-04-04
  • C++ 反射机制详解及实例代码

    C++ 反射机制详解及实例代码

    这篇文章主要介绍了C++ 反射机制详解及实例代码的相关资料,需要的朋友可以参考下
    2017-01-01
  • C++代码和可执行程序在x86和arm上的区别介绍

    C++代码和可执行程序在x86和arm上的区别介绍

    这篇文章主要介绍了C++代码和可执行程序在x86和arm上的区别,X86和ARM是占据CPU市场的两大处理器,各有优劣,本文给大家详细介绍了两者的区别,需要的朋友可以参考下
    2022-07-07
  • C++ OpenCV实战之标记点检测的实现

    C++ OpenCV实战之标记点检测的实现

    这篇文章主要介绍了如何利用C++ OpenCV实现关键点的检测,文中的示例代码讲解详细,对我们学习OpenCV有一定帮助,感兴趣的小伙伴可以了解一下
    2022-03-03
  • C++中关于this指针的入门介绍

    C++中关于this指针的入门介绍

    this 指针在C++类和对象中是个很方便实用的关键字,可以简化对象成员属性的调用,使代码表达的含义更加准确;在之前的学习中我们都可以判断变量所占内存空间大小,那么我们创建的类对象所占的内存空间怎么计算呢?想知道this的妙用和类对象占用的内存空间就来跟我学习吧
    2022-07-07
  • 关于C++静态成员函数访问非静态成员变量的问题

    关于C++静态成员函数访问非静态成员变量的问题

    静态成员函数不能访问非静态成员,这是因为静态函数属于类而不是属于整个对象,静态函数中的 member可能都没有分配内存。静态成员函数没有隐含的this自变量。所以,它就无法访问自己类的非静态成员
    2013-10-10
  • C语言详解格式控制符scanf与printf的输入输出

    C语言详解格式控制符scanf与printf的输入输出

    这篇文章主要介绍了C语言格式控制符中输入scanf()和输出printf()的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2022-04-04
  • Qt实现编辑数据库数据的方法详解

    Qt实现编辑数据库数据的方法详解

    这篇文章主要为大家详细介绍了Qt是如何实现编辑数据库数据的,文中的示例代码简洁易懂,对我们深入了解QT有一定的帮助,感兴趣的小伙伴可以了解一下
    2023-02-02

最新评论