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);//指定对应客户端发送数据

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值