【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 服务器和客户端都可以相互发送数据,不需要建立连接。

相关推荐
Cinema KI5 小时前
C++11(下) 入门三部曲终章(基础篇):夯实语法,解锁基础编程能力
开发语言·c++
燃于AC之乐5 小时前
深入解剖STL List:从源码剖析到相关接口实现
c++·stl·list·源码剖析·底层实现
枫叶丹45 小时前
【Qt开发】Qt界面优化(一)-> Qt样式表(QSS) 背景介绍
开发语言·前端·qt·系统架构
汉克老师5 小时前
GESP2025年6月认证C++二级( 第一部分选择题(9-15))
c++·循环结构·求余·gesp二级·gesp2级·整除、
不想睡觉_5 小时前
优先队列priority_queue
c++·算法
rainbow688916 小时前
EffectiveC++入门:四大习惯提升代码质量
c++
秋邱16 小时前
用 Python 写出 C++ 的性能?用CANN中PyPTO 算子开发硬核上手指南
开发语言·c++·python
我在人间贩卖青春16 小时前
C++之析构函数
c++·析构函数
我在人间贩卖青春17 小时前
C++之数据类型的扩展
c++·字符串·数据类型
明月醉窗台17 小时前
qt使用笔记六之 Qt Creator、Qt Widgets、Qt Quick 详细解析
开发语言·笔记·qt