QT备忘录(4)-QTcpServer高并发多线程处理多个Socket客户端

本文介绍QTcpServer多线程处理多个客户端的方法。

//TcpServer.h
#ifndef TCPSERVER_H
#define TCPSERVER_H

#include 
#include "TcpSocket.h"
#include 
#include 

class TcpServer : public QTcpServer
{
    Q_OBJECT
public:
    TcpServer(const std::string &ip, int port, QTcpServer *parent = NULL);
    ~TcpServer();

protected:
    void incomingConnection(qintptr socketDescriptor);
private slots:
    void SocketDisconn();

private:
    QList m_socketList;
};

#endif // TCPSERVER_H

//TcpServer.cpp
#include "TcpServer.h"

TcpServer::TcpServer(const std::string &ip, int port, QTcpServer *parent) : QTcpServer(parent)
{
    bool bsucc;
    if (ip.empty())
    {
        bsucc = this->listen(QHostAddress::AnyIPv4, port);
    }
    else
    {
        bsucc = this->listen(QHostAddress(ip.c_str()), port);
    }
}

TcpServer::~TcpServer()
{
    QList<TcpSocket*>::iterator it = m_socketList.begin();
    for (; it != m_socketList.end(); )
    {
        TcpSocket* sock = *it;
        it = m_socketList.erase(it);
        sock->deleteLater();
//        delete sock;
        sock = NULL;
    }
    m_socketList.clear();
    this->close();

}

void TcpServer::incomingConnection(qintptr socketDescriptor)
{
    TcpSocket *socket = new TcpSocket(socketDescriptor);
    m_socketList.append(socket);
    connect(socket, SIGNAL(readyRead()), socket, SLOT(ReadAndParseData())); // 会移进线程里
//    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));

    QThread *thread = new QThread();
    connect(socket, SIGNAL(disconnected()), thread, SLOT(quit()));
    connect(thread,SIGNAL(finished()),socket,SLOT(deleteLater()));

    socket->moveToThread(thread);
    thread->start();
    emit newConnection();   //文档要求继承本函数需要发射此信号,此处没有与此信号连接的槽
}

void TcpServer::SocketDisconn()
{
//    TcpSocket* socket = (TcpSocket*)sender();
//    QList::iterator it;
//    for(it=m_socketList.begin();it!=m_socketList.end();it++)
//    {
//        m_socketList.erase(it);
//        socket->deleteLater();
        delete socket;
//        socket = NULL;
//    }
}

//TcpSocket.h
#ifndef TCPSOCKET_H
#define TCPSOCKET_H

#include 
#include 

class TcpSocket : public QTcpSocket
{
    Q_OBJECT
public:
    TcpSocket(int socketdesc,QTcpSocket *parent = NULL);
    ~TcpSocket();

private slots:
    void ReadAndParseData();
    void SocketErr(QAbstractSocket::SocketError socketError);
private:
    QString m_recvDataStr;
};

#endif // TCPSOCKET_H


//TcpSocket.cpp
#include "TcpSocket.h"

TcpSocket::TcpSocket(int sock, QTcpSocket *parent) : QTcpSocket(parent)
{
    this->setSocketDescriptor(sock);
    connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(SocketErr(QAbstractSocket::SocketError)));
}

TcpSocket::~TcpSocket()
{

}

// 将会移进线程里面运行
void TcpSocket::ReadAndParseData()
{
    TcpSocket *socket = (TcpSocket*)sender();
    QString recvStr = socket->readAll();
    m_recvDataStr += recvStr;
    qDebug()<<m_recvDataStr<<socket->localAddress().toString();
    // 对数据的处理
}

void TcpSocket::SocketErr(QAbstractSocket::SocketError socketError)
{
    TcpSocket *socket = (TcpSocket*)sender();
}




调用方法:
TcpServer * mTcpServer
mTcpServer = new TcpServer(“IP”,“端口”);

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

你可能感兴趣的:(QT备忘录)