Qt网络编程——UDP

UDP

UDP(User Datagram Protocol,用户数据报协议)是一个轻量级的、不提供可靠性保证的、面向数据报的无连接协议,用于可靠性不是非常重要的情况。例如,传感器数据传输:一些传感器数据,如温度、湿度等环境监测数据,可能需要实时传输,但对于丢失一些数据并不是很敏感。UDP 能够提供更低的延迟,因为他没有 TCP 那样的握手和连接管理过程。

UDP 一般分为发送端和接收端,如图所示:

QUdpSocket 类用来发送和接收 UDP 数据报,继承自 QAbstractSocket。这里的 Socket 就是所谓的"套接字",简单来说,套接字就是一个 IP 地址加一个 port 端口号。其中,IP 地址指定了网络中的一台主机,而端口号指定了该主机上的一个网络程序,这样使用套接字就可以实现网络上两台主机的两个应用程序之间的通信。

发送端

widget.h

C++ 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QUdpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

protected slots:
    //! 发送数据报
    void on_btnSendMsg_clicked();

private:
    Ui::Widget *ui;

    QUdpSocket *m_udpSocket{};
};
#endif // WIDGET_H

widget.cpp

C++ 复制代码
#include "widget.h"
#include "./ui_widget.h"

#include <QUdpSocket>
#include <QNetworkDatagram>

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

    m_udpSocket = new QUdpSocket(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_btnSendMsg_clicked()
{
    QString msg = ui->textEdit->toPlainText();
    m_udpSocket->writeDatagram(msg.toLocal8Bit(), QHostAddress("192.168.0.202"), 1234);
}

发送界面展示:

接收端

widget.h

C++ 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QUdpSocket>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    //! 处理挂起数据报
    void processPendingDatagram();

private:
    Ui::Widget *ui;

    QUdpSocket *m_udpSocket{};
};
#endif // WIDGET_H

widget.cpp

C++ 复制代码
#include "widget.h"
#include "./ui_widget.h"

#include <QUdpSocket>
#include <QNetworkDatagram>

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

    m_udpSocket = new QUdpSocket(this);
    bool ret = m_udpSocket->bind(QHostAddress::Any, 1234);
    if (!ret) {
        qDebug() << "udp bind failed !";
    }
    connect(m_udpSocket, &QUdpSocket::readyRead, this, &Widget::processPendingDatagram);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::processPendingDatagram()
{
    if (!m_udpSocket->hasPendingDatagrams()
        || m_udpSocket->pendingDatagramSize() <= 0) {
        return;
    }

    while (m_udpSocket->hasPendingDatagrams()) {
        ui->textEdit->insertPlainText(m_udpSocket->receiveDatagram().data());
    }
}

接收界面展示:

总结

QUdpSocket以数据报传输数据,而不是连续的数据流。由于少了连接,客户端与服务端没有太大区别,所以可以看作只有发送端和接收端。无论是发送端还是接收端,都只有一个套接字,也就是 QUdpSocket。此外,UDP 通信中没有监听 listen(),只有绑定 bind(),往套接字中读写数据用 readDataGram()和writeDataGram()(不能超过512字节)。

相关推荐
Quz1 天前
QML Hello World 入门示例
qt
xcyxiner4 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner5 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner5 天前
DicomViewer (添加模型类)3
qt
xcyxiner6 天前
DicomViewer (目录调整) 2
qt
xcyxiner6 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
网络研究院8 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智8 天前
ARP代理--工作原理
运维·网络·arp·arp代理
treesforest8 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
shushangyun_8 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化