QT 中 UDP 的使用

目录

[一、UDP 简介](#一、UDP 简介)

[二、QT 中 UDP 编程的基本步骤](#二、QT 中 UDP 编程的基本步骤)

(一)包含头文件

[(二)创建 UDP 套接字对象](#(二)创建 UDP 套接字对象)

(三)绑定端口

(四)发送数据

(五)接收数据

三、完整示例代码

(一)发送端代码

(二)接收端代码

四、总结


一、UDP 简介

UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议。与 TCP 相比,UDP 在数据传输时不需要建立连接,也不保证数据的可靠传输、顺序到达以及不重复。这使得 UDP 具有较低的开销和较高的传输效率,适用于对实时性要求较高,而对数据准确性要求相对较低的场景,如视频流、音频流传输等。

二、QT 中 UDP 编程的基本步骤

在 QT 框架下进行 UDP 编程,主要涉及以下几个关键步骤。

(一)包含头文件

首先,在源文件中需要包含QUdpSocket头文件,它提供了 UDP 套接字的功能实现。

cpp 复制代码
#include <QUdpSocket>

(二)创建 UDP 套接字对象

在需要使用 UDP 的类中,声明一个QUdpSocket类型的成员变量。

cpp 复制代码
class MyUdpClass : public QObject
{
    Q_OBJECT
public:
    MyUdpClass(QObject *parent = nullptr);
private:
    QUdpSocket *udpSocket;
};

在类的构造函数中,初始化这个 UDP 套接字对象。

cpp 复制代码
MyUdpClass::MyUdpClass(QObject *parent) : QObject(parent)
{
    udpSocket = new QUdpSocket(this);
}

(三)绑定端口

为了能够接收和发送数据,需要将 UDP 套接字绑定到一个特定的端口上。可以使用bind函数进行绑定。

cpp 复制代码
if (!udpSocket->bind(12345))
{
    qDebug() << "Failed to bind port";
    return;
}

这里尝试将 UDP 套接字绑定到端口 12345,如果绑定失败,会输出错误信息。

(四)发送数据

使用writeDatagram函数来发送 UDP 数据报。该函数需要指定发送的数据、目标主机的 IP 地址和端口号。

cpp 复制代码
QByteArray data = "Hello, UDP!";
QHostAddress destAddress("192.168.1.100");
quint16 destPort = 54321;
qint64 bytesSent = udpSocket->writeDatagram(data, destAddress, destPort);
if (bytesSent == -1)
{
    qDebug() << "Failed to send data";
}

这段代码将字符串"Hello, UDP!"发送到目标 IP 地址为192.168.1.100,端口号为 54321 的主机上。如果发送失败,会输出相应的错误信息。

(五)接收数据

为了接收数据,需要连接QUdpSocket的readyRead信号到一个槽函数,当有数据可读时,该槽函数会被调用。

cpp 复制代码
connect(udpSocket, &QUdpSocket::readyRead, this, &MyUdpClass::readPendingDatagrams);

在槽函数readPendingDatagrams中,通过readDatagram函数读取数据。

cpp 复制代码
void MyUdpClass::readPendingDatagrams()
{
    while (udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
        qDebug() << "Received datagram:" << datagram << "from" << sender.toString() << ":" << senderPort;
    }
}

这段代码会不断读取所有接收到的 UDP 数据报,并输出数据内容、发送方的 IP 地址和端口号。

三、完整示例代码

下面是一个完整的 QT UDP 通信示例代码,包括发送端和接收端。

(一)发送端代码

cpp 复制代码
#include <QCoreApplication>
#include <QUdpSocket>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QUdpSocket udpSocket;
    QByteArray data = "Hello, UDP from sender!";
    QHostAddress destAddress("192.168.1.100");
    quint16 destPort = 54321;
    qint64 bytesSent = udpSocket.writeDatagram(data, destAddress, destPort);
    if (bytesSent == -1)
    {
        qDebug() << "Failed to send data";
    }
    else
    {
        qDebug() << "Data sent successfully";
    }

    return a.exec();
}

(二)接收端代码

cpp 复制代码
#include <QCoreApplication>
#include <QUdpSocket>
#include <QDebug>

class UdpReceiver : public QObject
{
    Q_OBJECT
public:
    UdpReceiver(QObject *parent = nullptr);
private slots:
    void readPendingDatagrams();
private:
    QUdpSocket *udpSocket;
};

UdpReceiver::UdpReceiver(QObject *parent) : QObject(parent)
{
    udpSocket = new QUdpSocket(this);
    if (!udpSocket->bind(54321))
    {
        qDebug() << "Failed to bind port";
        return;
    }
    connect(udpSocket, &QUdpSocket::readyRead, this, &UdpReceiver::readPendingDatagrams);
}

void UdpReceiver::readPendingDatagrams()
{
    while (udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
        qDebug() << "Received datagram:" << datagram << "from" << sender.toString() << ":" << senderPort;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    UdpReceiver receiver;

    return a.exec();
}

四、总结

通过以上步骤和示例代码,我们可以在 QT 中实现基本的 UDP 通信功能。在实际应用中,还需要根据具体需求对代码进行优化和扩展,例如处理网络异常、实现更复杂的数据结构传输等。UDP 在实时性要求高的场景中有着广泛的应用,掌握 QT 中 UDP 的编程方法,有助于开发出高效的网络应用程序。

相关推荐
郑州光合科技余经理3 分钟前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
知识分享小能手13 分钟前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
+VX:Fegn089533 分钟前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
阿里嘎多学长1 小时前
2026-09-20 GitHub 热点项目精选
开发语言·程序员·github·代码托管
江湖人称菠萝包3 小时前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter9-Qt Charts
笔记·qt·qt5
扶尔魔ocy3 小时前
【QT android】环境安装及第一个QT项目
qt·andriod开发
weixin_307779133 小时前
C++代码实现MATLAB中的ode23tb函数功能
开发语言·c++·算法·matlab
2601_966949653 小时前
为什么量化回测中 for 循环比 DataFrame 慢三个数量级?从向量化原理讲起
开发语言·python·pandas·股票数据·quantdash
边境悍匪5 小时前
蜗牛学苑 Java 智能体学习 Day45|Knife4j+SpringBoot3、书城项目整合 MyBatis 思维导图复盘
java·开发语言·vue.js·学习·spring
我的xiaodoujiao5 小时前
Django 基础知识详细图文教程 9-Django 模板引擎 2
开发语言·数据库·后端·django