主要思路:
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