QT6 Socket通讯封装(TCP/UDP)

为大家分享一下最近封装的以太网socket通讯接口

效果演示

如图,界面还没优化,后续更新

废话不多说直接上教程

添加库

如果为qmake项目中,在.pro文件添加 QT += network

cpp 复制代码
QT       += core gui
QT       += network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

Socket封装

头文件// SocketManager.h

cpp 复制代码
#ifndef SOCKETMANAGER_H
#define SOCKETMANAGER_H


#include <QObject>
#include <QTcpSocket>
#include <QTcpServer>
#include <QUdpSocket>
#include <functional>

class SocketManager : public QObject
{
    Q_OBJECT

public:
    enum class Protocol { TCP, UDP };

    explicit SocketManager(QObject *parent = nullptr);
    ~SocketManager();

    // Set the callback for incoming messages
    void setMessageCallback(const std::function<void(const QByteArray &)> &callback);

    // Initialize the socket
    bool initialize(Protocol protocol, const QString &host, quint16 port, bool isServer = false);

    // Send a message
    qint64 sendMessage(const QByteArray &message);

private slots:
    void onReadyRead();

private:
    Protocol m_protocol;
    QTcpSocket *m_tcpSocket = nullptr;
    QTcpServer *m_tcpServer = nullptr;
    QUdpSocket *m_udpSocket = nullptr;
    std::function<void(const QByteArray &)> m_messageCallback;

    void handleIncomingConnection();
};

#endif // SOCKETMANAGER_H

源文件// SocketManager.cpp

cpp 复制代码
#include "SocketManager.h"

SocketManager::SocketManager(QObject *parent)
    : QObject(parent)
{
}

SocketManager::~SocketManager()
{
    if (m_tcpSocket) delete m_tcpSocket;
    if (m_tcpServer) delete m_tcpServer;
    if (m_udpSocket) delete m_udpSocket;
}

void SocketManager::setMessageCallback(const std::function<void(const QByteArray &)> &callback)
{
    m_messageCallback = callback;
}

bool SocketManager::initialize(Protocol protocol, const QString &host, quint16 port, bool isServer)
{
    m_protocol = protocol;

    if (protocol == Protocol::TCP) {
        if (isServer) {
            m_tcpServer = new QTcpServer(this);
            connect(m_tcpServer, &QTcpServer::newConnection, this, &SocketManager::handleIncomingConnection);
            return m_tcpServer->listen(QHostAddress(host), port);
        } else {
            m_tcpSocket = new QTcpSocket(this);
            m_tcpSocket->connectToHost(host, port);
            connect(m_tcpSocket, &QTcpSocket::readyRead, this, &SocketManager::onReadyRead);
            return m_tcpSocket->waitForConnected();
        }
    } else if (protocol == Protocol::UDP) {
        m_udpSocket = new QUdpSocket(this);
        connect(m_udpSocket, &QUdpSocket::readyRead, this, &SocketManager::onReadyRead);
        return m_udpSocket->bind(QHostAddress(host), port);
    }

    return false;
}

qint64 SocketManager::sendMessage(const QByteArray &message)
{
    if (m_protocol == Protocol::TCP && m_tcpSocket) {
        return m_tcpSocket->write(message);
    } else if (m_protocol == Protocol::UDP && m_udpSocket) {
        return m_udpSocket->writeDatagram(message, QHostAddress::Broadcast, m_udpSocket->localPort());
    }

    return -1;
}

void SocketManager::onReadyRead()
{
    if (m_protocol == Protocol::TCP && m_tcpSocket) {
        QByteArray data = m_tcpSocket->readAll();
        if (m_messageCallback) {
            m_messageCallback(data);
        }
    } else if (m_protocol == Protocol::UDP && m_udpSocket) {
        while (m_udpSocket->hasPendingDatagrams()) {
            QByteArray data;
            data.resize(m_udpSocket->pendingDatagramSize());
            m_udpSocket->readDatagram(data.data(), data.size());
            if (m_messageCallback) {
                m_messageCallback(data);
            }
        }
    }
}

void SocketManager::handleIncomingConnection()
{
    if (m_tcpServer) {
        m_tcpSocket = m_tcpServer->nextPendingConnection();
        connect(m_tcpSocket, &QTcpSocket::readyRead, this, &SocketManager::onReadyRead);
    }
}

使用方式

首先引入#include "SocketManager.h"

初始化

通过enum class Protocol { TCP, UDP };来选择TCP/UDP

通过第三个参数来决定如果是TCP的话是Service服务端还是Client客户端

cpp 复制代码
    socketManager =  new SocketManager(this);

    if (socketManager->initialize(SocketManager::Protocol::UDP, "127.0.0.1", 12345, false)) {
        qDebug() << "TCP Client initialized.";
    }else{
        qDebug() << "TCP Client fail.";
    }


    socketManager->setMessageCallback([](const QByteArray &message) {
        qDebug() << "Received message:" << message;
    });

创建回调函数

收到消息通过回调函数的方式来接收数据

cpp 复制代码
socketManager->setMessageCallback([](const QByteArray &message) {
        qDebug() << "Received message:" << message;
    });

最后,我将项目放到Github,GitHub - xiugou798/QT6-Socket-Demo,欢迎大家优化修改

相关推荐
虎头金猫4 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
wuyk5554 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
QYRdata4 天前
年均增速24.2%!机器人数据湖未来六年增长动能强劲
网络·机器人·服务发现
CHENKONG_CK4 天前
破解制鞋打磨痛点:RFID赋能去毛刺工序自动化升级
网络·单片机·嵌入式硬件·网络协议·tcp/ip
chshang19924 天前
工业路由器是什么?浅谈5G工业网络中的IR602
网络·物联网·5g·智能路由器
萧瑟余晖4 天前
Netty 核心组件与 Reactor 模型详解
网络·架构
ITxiaobing20234 天前
IP 定位服务选型指南:从准确率到工程落地的技术考察
linux·服务器·网络
wuyk5554 天前
【Socket 进阶之路】第 9 章 Linux 网络服务量产稳定性优化|心跳保活、TIME_WAIT、SO_LINGER、内存池、断线重连、完整异常防护框架
linux·服务器·开发语言·网络·物联网
z落落4 天前
C#UDP+串口服务端+UDP 客户端(含 CRC16 校验)
网络·网络协议·udp
云运维笔记4 天前
华为设备IP地址配置全攻略
运维·网络·计算机网络·华为