当前位置: 首页 > article >正文

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


http://www.kler.cn/a/232468.html

相关文章:

  • 智慧建造-运用Trimble技术将梦幻水族馆变为现实【上海沪敖3D】
  • C#中 layout的用法
  • 〔 MySQL 〕数据类型
  • 大数据新视界 -- 大数据大厂之 Impala 性能飞跃:动态分区调整的策略与方法(上)(21 / 30)
  • 文件输入输出——NOI
  • WebAssembly在现代Web开发中的应用
  • 前端JavaScript篇之对原型、原型链的理解、原型修改、重写、原型链指向
  • 职业性格测试在求职应聘跳槽中的应用
  • Nginx方向代理和负载均衡配置
  • Unity3d Shader篇(六)— BlinnPhong高光反射着色器
  • PyTorch自动微分模块torch.autograd的详细介绍
  • Top 20 Docker 面试题(附答案)
  • 时间序列预测 —— DeepAR 模型
  • RedissonClient妙用-分布式布隆过滤器
  • 解锁机器学习多类分类之门:Softmax函数的全面指南
  • 详细关于如何解决mfc140.dll丢失的步骤,有效修复mfc140.dll文件丢失的问题。
  • l + r >> 1; 的含义
  • 10分钟快速入门正则表达式
  • 100天精通Python(实用脚本篇)——第115天:基于selenium实现反反爬策略之隐藏浏览器指纹特征
  • 排序(2)(希尔排序)
  • RibbonOpenFeign源码(待完善)
  • C语言操作符超详细总结
  • 第十六篇【传奇开心果系列】Python的OpenCV库技术点案例示例:图像质量评估
  • 前端框架学习 Vue(3)vue生命周期,钩子函数,工程化开发脚手架CLI,组件化开发,组件分类
  • Git分支常用指令
  • LabVIEW多任务实时测控系统