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

相关推荐
虾球xz2 小时前
CppCon 2016 学习:Using Weakly Ordered C++ Atomics Correctly
开发语言·c++·学习
虾球xz10 小时前
CppCon 2016 学习:GAME ENGINE USING C++11
大数据·开发语言·c++·学习
虾球xz10 小时前
CppCon 2016 学习:fixed_point Library
开发语言·c++·学习
HaiQinyanAN10 小时前
【学习笔记】nlohmannjson&&cjson
c++·笔记·学习·json
C语言小火车10 小时前
【C语言】银行账户管理系统丨源码+解析
c语言·c++·算法·课程设计
Wyn_10 小时前
【QT】自定义QWidget设置圆角+边框(重绘paintEvent)
qt·qwidget
东方芷兰11 小时前
Leetcode 刷题记录 17 —— 堆
java·c++·b树·算法·leetcode·职场和发展
lzb_kkk11 小时前
【MFC】编辑框、下拉框、列表控件
c语言·开发语言·c++·mfc·1024程序员节
漫步企鹅11 小时前
【PDF】Qt生成PDF文件,占用存储小
c++·qt·pdf
蚂蚁取经11 小时前
MFC动态链接库相关知识
c++·mfc