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

相关推荐
2301_8076114924 分钟前
77. 组合
c++·算法·leetcode·深度优先·回溯
小刘同学++44 分钟前
Qt 处理 XML 数据
xml·qt
Quz1 小时前
使用Qt Quick Controls创建自定义日历组件
qt·ui·交互
微网兔子1 小时前
伺服器用什么语言开发呢?做什么用什么?
服务器·c++·后端·游戏
YuforiaCode1 小时前
第十三届蓝桥杯 2022 C/C++组 修剪灌木
c语言·c++·蓝桥杯
YOULANSHENGMENG1 小时前
linux 下python 调用c++的动态库的方法
c++·python
CodeWithMe2 小时前
【C++】STL之deque
开发语言·c++
炯哈哈2 小时前
【上位机——MFC】运行时类信息机制
开发语言·c++·mfc·上位机
rigidwill6663 小时前
LeetCode hot 100—最长有效括号
数据结构·c++·算法·leetcode·职场和发展
阳光_你好4 小时前
C++/Qt中QActionGroup类用法
c++·qt