QT QTcpServer实现多个客户端连接

主要思路:
1、重写QTcpServer的incomingConnection
2、如果信号槽定义在线程的run()函数中,那么执行槽函数时并不是在当前线程中。所以采用在第一个线程中再创建一个线程去执行socket的槽函数
3、注意所有new出的对象的释放及释放顺序。要不会造成内存泄漏或程序崩溃

#include "dialog.h"
#include "ui_dialog.h"
#include <QTcpServer>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    
    
    ui->setupUi(this);
    m_server = new MyServer();
    m_server->listen(QHostAddress("127.0.0.1"),1234);
}

Dialog::~Dialog()
{
    
    
    delete ui;
    if(m_server != NULL)
    {
    
    
        delete m_server;
        m_server = NULL;
    }
}

重写QTcpServer中的incomingConnection函数,当监听到有连接时,会调用此函数
myserver.cpp

void MyServer::incomingConnection(qintptr socketDescriptor)
{
    
    
    qDebug() << "主线程id:" << QThread::currentThread();
    Thread1 *thread = new Thread1(socketDescriptor);
    connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));//删除thread对象
    thread->start();
}

thread1.cpp

#include "thread1.h"
#include "thread2.h"
#include <QEventLoop>

Thread1::Thread1(int socketDescriptor,QObject *parent) :
    QThread(parent)
{
    
    
    m_socketDescriptor = socketDescriptor;
}

Thread1::~Thread1()
{
    
    
    qDebug() << "调用线程1析构函数" << QThread::currentThread();
    if(m_socket != NULL)
    {
    
    
        delete m_socket;
        m_socket = NULL;
    }
}

void Thread1::run()
{
    
    
    qDebug() << "启动Thread1 run()函数" << QThread::currentThread();
    m_socket = new QTcpSocket();
    if(m_socket->setSocketDescriptor(m_socketDescriptor))
    {
    
    
        qDebug()<<"setSocketDescriptor  success!";
    }
    else
    {
    
    
        qDebug()<<"setSocketDescriptor  error!";
    }

    //创建线程2,处理socket槽函数
    Thread2 *thread2 = new Thread2(m_socket);
    thread2->start();

    QEventLoop loop;
    connect(thread2, SIGNAL(finished()),&loop, SLOT(quit()));//阻塞thread1,直到thread2退出run()
    loop.exec();

    //删除thread2
    if(thread2 != NULL)
    {
    
    
        delete thread2;
        thread2 = NULL;
    }
    qDebug() << "退出Thread1 run()函数" << QThread::currentThread();
}

thread2.cpp

#include "thread2.h"
#include <QEventLoop>

Thread2::Thread2(QTcpSocket *socket,QObject *parent) :
    QThread(parent)
{
    
    
    m_socket = socket;
}

Thread2::~Thread2()
{
    
    
    qDebug() << "调用Thread2析构函数" << QThread::currentThread();
}

void Thread2::run()
{
    
    
    qDebug() << "启动Thread2 run()函数" << QThread::currentThread();

    connect(m_socket,SIGNAL(readyRead()),this,SLOT(readData()));

    QEventLoop loop;
    QObject::connect(m_socket, SIGNAL(disconnected()), &loop, SLOT(quit()));//socket断开退出thread2 run()函数
    loop.exec();

    qDebug() << "退出Thread2 run()函数" << QThread::currentThread();
}

void Thread2::readData()
{
    
    
    qDebug() << "[" << QThread::currentThread() << "]" << "读取客户端数据:" << m_socket->readAll();
}

输出结果

主线程id: QThread(0x6b1818) 
启动Thread1 run()函数 Thread1(0x6bdeb0) 
setSocketDescriptor  success! 
启动Thread2 run()函数 Thread2(0x131ed3f0) 
[ Thread1(0x6bdeb0) ] 读取客户端数据: "客户端:111" 
退出Thread2 run()函数 Thread2(0x131ed3f0) 
调用Thread2析构函数 Thread1(0x6bdeb0) 
退出Thread1 run()函数 Thread1(0x6bdeb0) 
调用线程1析构函数 QThread(0x6b1818) 

程序代码:https://download.csdn.net/download/sinat_33859977/11623320

猜你喜欢

转载自blog.csdn.net/sinat_33859977/article/details/100110460