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,欢迎大家优化修改

相关推荐
jiayong238 分钟前
前端面试题库 - 浏览器与网络篇
前端·网络·面试
pengyi87101522 分钟前
共享 IP 防封维护策略,降低被封率、延长 IP 寿命
网络·网络协议·tcp/ip
制造业的搬运工1 小时前
高端电路板哪家好:专业视角下的选择逻辑
网络·pcb工艺·pcb
Yeats_Liao1 小时前
物联网接入层技术剖析(二):epoll到底是怎么工作的
java·linux·网络·物联网·信息与通信
机器学习之心1 小时前
基于贝叶斯优化超参数的图卷积网络(BO-GCN)分类预测模型(附实验文档+Matlab代码)
网络·matlab·分类·分类预测模型·bo-gcn
上海云盾-小余1 小时前
内网终端安全管控:筑牢企业内部网络入侵防火墙
服务器·网络·安全
思茂信息1 小时前
CST案例:可调谐全硅手性超表面在太赫兹频段
网络·人工智能·算法·重构·cst·电磁仿真
Bat U2 小时前
JavaEE|网络原理TCP/IP
网络·网络协议·tcp/ip
智慧光迅AINOPOL2 小时前
OLT有哪些形态:框式、盒式,模块型,分别应用哪些场景?
网络·智能路由器
不仙5202 小时前
Rocky Linux 8.10 TigerVNC 安装配置指南
linux·服务器·网络