为大家分享一下最近封装的以太网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,欢迎大家优化修改