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

相关推荐
白帽黑客沐瑶2 天前
【网络安全就业】信息安全专业的就业前景(非常详细)零基础入门到精通,收藏这篇就够了
网络·安全·web安全·计算机·程序员·编程·网络安全就业
树码小子2 天前
Java网络编程:(socket API编程:TCP协议的 socket API -- 回显程序的服务器端程序的编写)
java·网络·tcp/ip
绿箭柠檬茶2 天前
Ubuntu 服务器配置转发网络访问
服务器·网络·ubuntu
我是菜鸟0713号2 天前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_2 天前
QT(4)
开发语言·汇编·c++·qt·算法
FPGA_Linuxer2 天前
FPGA 40 DAC线缆和光模块带光纤实现40G UDP差异
网络协议·fpga开发·udp
real 12 天前
传输层协议UDP
网络·网络协议·udp
路由侠内网穿透2 天前
本地部署 GPS 跟踪系统 Traccar 并实现外部访问
运维·服务器·网络·windows·tcp/ip
喵手2 天前
玩转Java网络编程:基于Socket的服务器和客户端开发!
java·服务器·网络
徐子元竟然被占了!!2 天前
实验-基本ACL
网络