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字节)。

相关推荐
祺风挽楠11 分钟前
ansible编辑
网络·ansible
莫名的好感°44 分钟前
手机RAR解压怎么选?2026年二季度四款产品问答
服务器·网络·智能手机
AI科技星4 小时前
数术工坊第八卷:算力革命
c语言·开发语言·网络·量子计算·agi
金色熊族4 小时前
QTransform使用心得(二)--仿射变换、非仿射变换、矩阵
qt·线性代数·矩阵
liulilittle4 小时前
固定数组时间轮的槽过载优化:桶链表与批次执行
网络·数据结构·链表
行走__Wz4 小时前
【网工入门-eNSP模拟-05】静态路由
网络
xiangw@GZ4 小时前
802.11全系列标准调制编码与速率档对应关系
网络·单片机·嵌入式硬件·架构
liulilittle5 小时前
KCC:在 BBR 思路上的一次探索
网络·tcp/ip·算法·bbr·通信·拥塞控制·kcc
27669582926 小时前
泡泡玛特app 腾讯企业加固/支付宝加固脱修frida rpc调用
网络·网络协议·rpc·frida·泡泡玛特·ppmt·泡泡玛特app-rpc调用
其实防守也摸鱼6 小时前
软件安全与漏洞--Windows底层原理与软件逆向工程基础
linux·网络·数据库·算法·安全·安全架构·软件安全与漏洞