QTcpServer使用多线程处理连接进来的QTcpSocket

参考:https://blog.csdn.net/qqwangfan/article/details/78271110

 

  1.  
    // qtcpserver使用多线程处理连进来的qtcpsocket端
  2.  
    //头文件
  3.  
    #pragma once
  4.  
    #include <qtcpserver.h>
  5.  
    #include <qtcpsocket.h>
  6.  
    #include <qmap.h>
  7.  
    // tcpsocket从qtcpsocket继承下来,需要将tcpsocket移到线程里使用,故tcpsocket需处理的都放进槽里,使用信号发射后,槽函数就在线程里运行
  8.  
    // tcpserver从QTcpServer继承下来,重载incomingConnection函数
  9.  
     
  10.  
    class TcpSocket : public QTcpSocket
  11.  
    {
  12.  
    Q_OBJECT
  13.  
    public:
  14.  
    TcpSocket(int socketdesc,QTcpSocket *parent = NULL);
  15.  
    ~TcpSocket();
  16.  
     
  17.  
    private slots:
  18.  
    void ReadAndParseData();
  19.  
    void SocketErr(QAbstractSocket::SocketError socketError);
  20.  
    private:
  21.  
    QString m_recvDataStr;
  22.  
    };
  23.  
     
  24.  
    class TcpServer : public QTcpServer
  25.  
    {
  26.  
    Q_OBJECT
  27.  
    public:
  28.  
    TcpServer(const std::string &ip, int port, QTcpServer *parent = NULL);
  29.  
    ~TcpServer();
  30.  
     
  31.  
    protected:
  32.  
    void incomingConnection(qintptr socketDescriptor);
  33.  
     
  34.  
    private slots:
  35.  
    void SocketDisconn();
  36.  
     
  37.  
    private:
  38.  
    QList<TcpSocket*> m_socketList;
  39.  
    };
  40.  
     
  41.  
     
  42.  
    //cpp文件
  43.  
    #include <qthread.h>
  44.  
    #include <qlist.h>
  45.  
    #include "TcpServer.h"
  46.  
    #include "log.h"
  47.  
     
  48.  
    TcpSocket::TcpSocket(int sock, QTcpSocket *parent) : QTcpSocket(parent)
  49.  
    {
  50.  
    this->setSocketDescriptor(sock);
  51.  
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketErr(QAbstractSocket::SocketError)));
  52.  
    }
  53.  
     
  54.  
    TcpSocket::~TcpSocket()
  55.  
    {
  56.  
     
  57.  
    }
  58.  
     
  59.  
    // 将会移进线程里面运行
  60.  
    void TcpSocket::ReadAndParseData()
  61.  
    {
  62.  
    TcpSocket *socket = (TcpSocket*)sender();
  63.  
    QString recvStr = socket->readAll();
  64.  
    m_recvDataStr += recvStr;
  65.  
    // 对数据的处理
  66.  
    }
  67.  
     
  68.  
    void TcpSocket::SocketErr(QAbstractSocket::SocketError socketError)
  69.  
    {
  70.  
    TcpSocket *socket = (TcpSocket*)sender();
  71.  
    WLog(LOG_ERR, "socket[%d] ip[%s] port[%d] err[%s]", socket->socketDescriptor(),
  72.  
    socket->peerAddress().toString().toLocal8Bit().data(),socket->peerPort(),socket->errorString().toLocal8Bit().data());
  73.  
    }
  74.  
     
  75.  
     
  76.  
    TcpServer::TcpServer(const std::string &ip, int port, QTcpServer *parent) : QTcpServer(parent)
  77.  
    {
  78.  
    bool bsucc;
  79.  
    if (ip.empty())
  80.  
    {
  81.  
    bsucc = this->listen(QHostAddress::AnyIPv4, port);
  82.  
    }
  83.  
    else
  84.  
    {
  85.  
    bsucc = this->listen(QHostAddress(ip.c_str()), port);
  86.  
    }
  87.  
     
  88.  
    WLog(LOG_INFO,"listen bsucc[%d],ip[%s] port[%d] errstr[%s]", bsucc,ip.c_str(),
  89.  
    port,this->errorString().toLocal8Bit().data());
  90.  
    }
  91.  
     
  92.  
    TcpServer::~TcpServer()
  93.  
    {
  94.  
    this->close();
  95.  
    /*QList<TcpSocket*>::iterator it = m_socketList.begin();
  96.  
    for (; it != m_socketList.end(); )
  97.  
    {
  98.  
    TcpSocket* sock = *it;
  99.  
    it = m_socketList.erase(it);
  100.  
    delete sock;
  101.  
    sock = NULL;
  102.  
    }
  103.  
    m_socketList.clear();*/
  104.  
    }
  105.  
     
  106.  
    /*
  107.  
    Note: If you want to handle an incoming connection as a new QTcpSocket object in another thread you have to
  108.  
    pass the socketDescriptor to the other thread and create the QTcpSocket object there and use its setSocketDescriptor() method.
  109.  
    */
  110.  
    void TcpServer::incomingConnection(qintptr socketDescriptor)
  111.  
    {
  112.  
    TcpSocket *socket = new TcpSocket(socketDescriptor);
  113.  
     
  114.  
    connect(socket, SIGNAL(readyRead()), socket, SLOT(ReadAndParseData())); // 会移进线程里
  115.  
    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
  116.  
     
  117.  
    QThread *thread = new QThread(socket); // 以socket为父类,当socket释放删除后也会删除线程,或者将线程的quit信号关联槽deleteLater()也可以达到效果
  118.  
    connect(socket, SIGNAL(disconnected()), thread, SLOT(quit()));
  119.  
    socket->moveToThread(thread);
  120.  
    thread->start();
  121.  
    emit newConnection(); //文档要求继承本函数需要发射此信号,此处没有与此信号连接的槽
  122.  
    }
  123.  
     
  124.  
    void TcpServer::SocketDisconn()
  125.  
    {
  126.  
    /*TcpSocket* socket = (TcpSocket*)sender();
  127.  
    QList<TcpSocket*>::iterator it = find(m_socketList.begin(), m_socketList.end(), socket);
  128.  
    if (it != m_socketList.end())
  129.  
    {
  130.  
    m_socketList.erase(it);
  131.  
    delete socket;
  132.  
    socket = NULL;
  133.  
    }*/
  134.  
    }

 

在外部使用TcpServer *server = new TcpServer(ip,port);即可作为服务器监听

 
posted @ 2021-04-25 22:21  狂客  阅读(1833)  评论(0编辑  收藏  举报