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 的编程方法,有助于开发出高效的网络应用程序。

相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner5 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz10 天前
QML Hello World 入门示例
qt
xcyxiner13 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner14 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript