zoukankan      html  css  js  c++  java
  • 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);即可作为服务器监听

     
  • 相关阅读:
    连续子数组的最大和
    最小的K个数
    数组中出现次数超过一半的数字
    字符串的排列
    二叉搜索树与双向链表
    复杂链表的复制
    二叉树中和为某一值的路径
    二叉搜索树的后序遍历序列
    Xcode5下去除Icon高光
    Unity3D-基本导航(NavMesh)功能实现
  • 原文地址:https://www.cnblogs.com/kuangke/p/14702427.html
Copyright © 2011-2022 走看看