Qt网络编程-QTcpServer的封装

简单封装Tcp服务器类,将QTcpServer移入线程

头文件:

#ifndef TCPSERVER_H
#define TCPSERVER_H

#include <QObject>

class QTcpSocket;
class QTcpServer;
class QThread;
class TcpServer : public QObject {
    Q_OBJECT
public:
    explicit TcpServer(const QString &ip, quint16 port,
                       QObject *parent = nullptr);
    ~TcpServer();
    bool startListening();
    void stopListen();

public slots:
    void write(const QString &ip, quint16 port, const QByteArray &data);

private slots:
    void handleNewConnect();

signals:
    void clientConnection(const QString &ip, quint16 port, bool connectState);
    void receiceSocketMessage(const QString &ip, quint16 port,
                              const QByteArray &data);

private:
    QString m_Ip;
    quint16 m_Port;
    QThread *m_Thread;
    QTcpServer *m_Server;
    QList<QTcpSocket *> m_Sockets;
};

#endif // TCPSERVER_H

源文件:

#include "tcpserver.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QThread>

TcpServer::TcpServer(const QString &ip, quint16 port, QObject *parent)
    : QObject(parent), m_Ip(ip), m_Port(port) {
    m_Server = new QTcpServer;
    m_Thread = new QThread;
    connect(m_Server, &QTcpServer::newConnection, this,
            &TcpServer::handleNewConnect);
    moveToThread(m_Thread);
    m_Thread->start();
}

TcpServer::~TcpServer() {
    if (nullptr != m_Server) {
        if (m_Server->isListening()) stopListen();
        m_Server->deleteLater();
        m_Server = nullptr;
    }
    if (nullptr != m_Thread) {
        if (m_Thread->isRunning()) {
            m_Thread->quit();
            m_Thread->wait();
        }
        m_Thread->deleteLater();
        m_Server = nullptr;
    }
}

bool TcpServer::startListening() {
    if (m_Server->isListening()) return true;
    return m_Server->listen(QHostAddress(m_Ip), m_Port);
}

void TcpServer::stopListen() {
    m_Server->close();
}

void TcpServer::write(const QString &ip, quint16 port, const QByteArray &data) {
    for (QTcpSocket *p : m_Sockets) {
        if (ip == p->peerAddress().toString() && port == p->peerPort()) {
            p->write(data);
            break;
        }
    }
}

void TcpServer::handleNewConnect() {
    QTcpSocket *socket = m_Server->nextPendingConnection();
    QString ip = socket->peerAddress().toString();
    quint16 port = socket->peerPort();
    bool contains = false;
    for (QTcpSocket *p : m_Sockets) {
        if (ip == p->peerAddress().toString() && port == p->peerPort()) {
            contains = true;
            break;
        }
    }
    if (!contains) m_Sockets.append(socket);
    emit clientConnection(ip, port, true);
    connect(socket, &QTcpSocket::disconnected, [=]() {
        emit clientConnection(ip, port, false);
        for (QTcpSocket *p : m_Sockets) {
            if (ip == p->peerAddress().toString() && port == p->peerPort()) {
                m_Sockets.removeOne(p);
                p->deleteLater();
                p = nullptr;
                break;
            }
        }
    });
    connect(socket, &QTcpSocket::readyRead, [=]() {
        QByteArray data = socket->readAll();
        emit receiceSocketMessage(ip, port, data);
    });
}

调用示例:

   TcpServer *server = new TcpServer("192.168.1.3", 12345);
    connect(server, &TcpServer::clientConnection,
            [=](const QString &ip, quint16 port, bool connectState) {
                //TODO 处理客户端连接
            });
    connect(server, &TcpServer::receiceSocketMessage,
            [=](const QString &ip, quint16 port, const QByteArray &data) {
                处理收到客户端消息
            });
   m_Server->startListening();
    QByteArray data;
   //TODO 处理发送数据
    m_Server->write("192.168.1.4", 12344, data);//指定对应客户端发送数据

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>