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

相关推荐
Junfeng的技术笔记6 小时前
基于 C++/Qt 的雷达回波信号检测与测距仿真系统
qt
Quz6 小时前
QML TableView:自定义样式与排序表格
qt
Quz6 小时前
QML TableView:可编辑表格与 SQLite 数据持久化
qt·sqlite
Quz6 小时前
QML ListView:C++ 数据模型与 ProxyModel 实时过滤
qt
Quz6 小时前
QML ListView 入门:自定义样式与数据交互
qt
cpp_learner7 小时前
QT 隐藏式密码鉴权:一键开启管理员模式
qt
虎头金猫6 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
wuyk5556 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
慧都小项6 天前
当边缘AI上产线:QtitanDocking 如何让工业 HMI 实现多视图协同
人工智能·qt·ui·边缘计算·qt6.3
QYRdata6 天前
年均增速24.2%!机器人数据湖未来六年增长动能强劲
网络·机器人·服务发现