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

相关推荐
亓才孓16 分钟前
[计算机网络]IP地址推行的“书同文,车同轨”
网络·tcp/ip·计算机网络·软件工程
小狮子安度因20 分钟前
DPDK用户态协议栈-TCP Posix API 2
网络·网络协议·tcp/ip
IpdataCloud23 分钟前
在 Linux 和 Windows 操作系统下查询局域网IP
linux·运维·tcp/ip
wendetaer30 分钟前
郑州大学计算机网络实验11 ARP协议探索和分析
linux·网络·计算机网络
寻找沙漠的人2 小时前
网络原理04
java·网络·java-ee
前端开发小司机2 小时前
怎么从零开始学黑客,黑客零基础怎么自学?
网络·安全·web安全·网络安全
Microsoft Word3 小时前
计算机网络 第五章 运输层
网络·计算机网络
朝阳…晚霞4 小时前
HCIE之OSPF基础(十九)
网络
VVVVWeiYee4 小时前
路由引入问题(双点双向路由回馈问题)
运维·服务器·网络·信息与通信
CodeGrindstone5 小时前
Muduo网络库解析 ---线程模块
网络·c++·tcp/ip