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

相关推荐
萧鼎12 分钟前
深入解析 Python 的 pytun 库:虚拟网络接口与隧道技术实战指南
服务器·网络·python
Yuki’1 小时前
网络编程---UDP
c语言·网络·网络协议·udp
鲸屿1951 小时前
python之socket网络编程
开发语言·网络·python
天天年年天天。2 小时前
TCP/IP、HTTP 和 HTTPS简介
网络
想睡hhh2 小时前
网络原理——传输层协议UDP
网络·网络协议·udp
SNAKEpc121382 小时前
QML和Qt Quick
c++·qt
PH_modest2 小时前
【Qt跬步积累】—— 初识Qt
开发语言·qt
lsnm3 小时前
【LINUX网络】IP——网络层
linux·服务器·网络·c++·网络协议·tcp/ip
楠枬4 小时前
ARP 协议
网络·网络协议·arp
wanhengidc4 小时前
云手机就是虚拟机吗?
运维·网络·安全·智能手机