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;
    });

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

相关推荐
_ZHOURUI_H_1 分钟前
Unity TCP底层极限拆解:粘包、半包、CRC、序列号、双缓冲到底怎么一起工作的?
网络·网络协议·tcp/ip·游戏·unity·游戏引擎·游戏开发
长江&后浪1 小时前
防火墙的描述
开发语言·网络·php
小新讲网安2 小时前
安全运营中心(SOC)建设实战:从SIEM到威胁狩猎全流程指南
网络·安全·web安全·网络安全·网安
SKYLAB012 小时前
打破智能家居生态壁垒|微喇智能 WKV553‑A 模组原生支持 Matter,解锁跨平台互联新体验
网络·智能家居
笨鸟先飞,勤能补拙3 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
KindSuper_liu3 小时前
Unity 游戏网络基础:从 TCP、UDP 到 HTTP、TLS 与 Best HTTP
网络·游戏·unity
caimouse3 小时前
ReactOS 图形系统分析(3):显示驱动 DDI framebuf.dll
linux·运维·网络
M158227690553 小时前
四通道 Profinet 转 Modbus RTU 网关 SG-PN-Modbus_4 全场景落地详解
网络·工控布线
佳児素花痴╮4 小时前
网络问题与基础理论
运维·服务器·网络
Oflycomm4 小时前
IPC网络摄像机与安防监控:Wi-Fi 6模组、AOV低功耗与边缘AI的产业落地
网络·人工智能·安防监控·wifi6·ipc网络摄像机