【QT5 网络编程示例】UDP 通信

文章目录

    • [UDP 通信](#UDP 通信)

UDP 通信

Qt 主要通过 QUdpSocket 类实现 UDP 通信。

常用方法

  • bind(QHostAddress, quint16 port):绑定指定 IP 和端口。
  • writeDatagram(QByteArray, QHostAddress, quint16 port):向指定地址和端口发送数据包。
  • readDatagram(QByteArray &buffer, QHostAddress *sender, quint16 *senderPort):读取接收到的数据包。
  • hasPendingDatagrams():检查是否有待处理的数据包。
  • pendingDatagramSize():获取下一个数据包的大小。

常用信号

  • readyRead():当有数据可读时触发。

下面给出一个简单示例:

https://github.com/BinaryAI-1024/QtStudy/tree/master/network/UDP

服务器端

cpp 复制代码
// udpserver.h
#ifndef UDPSERVER_H
#define UDPSERVER_H

#include <QUdpSocket>
#include <QObject>

class UdpServer : public QObject {
    Q_OBJECT
public:
    explicit UdpServer(QObject *parent = nullptr);
    ~UdpServer();

    void startServer(quint16 port); // 启动服务器

private slots:
    void onReadyRead(); // 处理接收的数据

private:
    QUdpSocket *udpSocket; // UDP 套接字
};

#endif // UDPSERVER_H
cpp 复制代码
// udpserver.cpp
#include "udpserver.h"
#include <QDebug>

// 构造函数,初始化 QUdpSocket 并连接 readyRead 信号
UdpServer::UdpServer(QObject *parent) : QObject(parent), udpSocket(new QUdpSocket(this)) {
    // 当有数据可读时,触发 onReadyRead 处理数据
    connect(udpSocket, &QUdpSocket::readyRead, this, &UdpServer::onReadyRead);
}

// 析构函数,关闭 UDP 套接字
UdpServer::~UdpServer() {
    udpSocket->close();
}

// 绑定端口
void UdpServer::startServer(quint16 port) {
    if (udpSocket->bind(QHostAddress::Any, port)) { // 绑定到所有可用的网络接口
        qDebug() << "UDP Server started on port" << port;
    } else {
        qDebug() << "UDP Server failed to start!";
    }
}

// 处理接收到的数据
void UdpServer::onReadyRead() {
    while (udpSocket->hasPendingDatagrams()) { // 检查是否有未处理的数据包
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize()); // 调整数组大小以容纳数据
        QHostAddress sender; // 发送方 IP 地址
        quint16 senderPort;  // 发送方端口号

        // 读取数据包,并获取发送方地址和端口
        udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
        qDebug() << "Received from" << sender.toString() << ":" << senderPort << "->" << datagram;

        // 发送响应数据回给客户端
        udpSocket->writeDatagram("Hello from server!", sender, senderPort);
    }
}

客户端

cpp 复制代码
// udpclient.h
#ifndef UDPCLIENT_H
#define UDPCLIENT_H

#include <QUdpSocket>
#include <QObject>

class UdpClient : public QObject {
    Q_OBJECT
public:
    explicit UdpClient(QObject *parent = nullptr);
    ~UdpClient();

    void sendMessage(const QString &message, const QString &host, quint16 port);

private slots:
    void onReadyRead(); // 处理服务器返回的数据

private:
    QUdpSocket *udpSocket;
};

#endif // UDPCLIENT_H
cpp 复制代码
// udpclient.cpp
#include "udpclient.h"
#include <QDebug>

// 构造函数,初始化 QUdpSocket 并连接 readyRead 信号
UdpClient::UdpClient(QObject *parent) : QObject(parent), udpSocket(new QUdpSocket(this)) {
    // 当有数据可读时,触发 onReadyRead 处理数据
    connect(udpSocket, &QUdpSocket::readyRead, this, &UdpClient::onReadyRead);
}

// 析构函数,关闭 UDP 套接字
UdpClient::~UdpClient() {
    udpSocket->close();
}

// 发送 UDP 数据到指定的 IP 和端口
void UdpClient::sendMessage(const QString &message, const QString &host, quint16 port) {
    udpSocket->writeDatagram(message.toUtf8(), QHostAddress(host), port);
}

// 处理接收到的数据
void UdpClient::onReadyRead() {
    while (udpSocket->hasPendingDatagrams()) { // 检查是否有未处理的数据包
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize()); // 调整数组大小以容纳数据
        udpSocket->readDatagram(datagram.data(), datagram.size()); // 读取数据包
        qDebug() << "Received from server:" << datagram; // 输出接收到的数据
    }
}

主函数

cpp 复制代码
// main.cpp
#include <QCoreApplication>
#include "udpserver.h"
#include "udpclient.h"

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 启动服务器
    UdpServer server;
    server.startServer(12345);

    // 启动客户端并发送消息
    UdpClient client;
    client.sendMessage("Hello from client!", "127.0.0.1", 12345);

    return a.exec();
}

运行结果:

plaintext 复制代码
UDP Server started on port 12345
Received from "::ffff:127.0.0.1" : 59792 -> "Hello from client!"
Received from server: "Hello from server!"

UDP 服务器和客户端都可以相互发送数据,不需要建立连接。

相关推荐
ALex_zry3 小时前
C++网络编程心跳机制与连接保活:长连接稳定性保障
开发语言·网络·c++
学嵌入式的小杨同学4 小时前
STM32 进阶封神之路(三十二):SPI 通信深度实战 —— 硬件 SPI 驱动 W25Q64 闪存(底层时序 + 寄存器配置 + 读写封装)
c++·stm32·单片机·嵌入式硬件·mcu·架构·硬件架构
好大哥呀5 小时前
C++ Web 编程
开发语言·前端·c++
Mr_Xuhhh5 小时前
LeetCode hot 100(C++版本)(上)
c++·leetcode·哈希算法
漫随流水5 小时前
c++编程:反转字符串(leetcode344)
数据结构·c++·算法
南境十里·墨染春水6 小时前
C++ 笔记 友元(面向对象)
开发语言·c++·笔记
C++ 老炮儿的技术栈6 小时前
分享一个安全的CString
c语言·c++·windows·git·安全·visual studio
桦07 小时前
[C++复习]:STL
开发语言·c++
苏宸啊8 小时前
rbtree封装map和set
c++
汉克老师8 小时前
GESP2025年6月认证C++三级( 第一部分选择题(1-8))
c++·二进制·原码·补码·gesp三级·gesp3级·八进制、