学习QThread主要是为了仿照VC下的FTP服务器写个QT版本。不多说,上图。
FTP服务器的软件结构在上面的分析中就已经解释了,今天要解决的就是让每一个客户端的处理过程都可以按一个线程来单独跑。先给出上面3个类的cpp文件,再给出现象。
1、QListenSocket类
1 #include "qlistensocket.h" 2 #include <QTcpSocket> 3 #include <QDebug> 4 5 QListenSocket::QListenSocket(QObject *parent,int port):QTcpServer(parent) 6 { 7 listen(QHostAddress::LocalHost,port); 8 } 9 10 void QListenSocket::incomingConnection(int socketDescriptor) 11 { 12 qDebug()<<"A new Client Connnected!"; 13 14 QControlThread *tmp =new QControlThread(socketDescriptor,this); 15 ClientList.append(tmp); 16 17 tmp->start(); 18 }
2、QControlThread类
1 //线程构造函数 2 QControlThread::QControlThread(qintptr socketDescriptor,QObject *parent):QThread(parent) 3 { 4 qDebug()<<"QControlThread Construct Function threadid:"<<QThread::currentThreadId(); 5 6 m_ControlSocketObj = new QControlSocketObj(socketDescriptor,0); 7 8 m_ControlSocketObj->moveToThread(this); //将m_ControlSocketObj和它的槽函数都移到本线程中来处理 9 } 10 11 QControlThread::~QControlThread() 12 { 13 delete m_ControlSocketObj; 14 15 quit(); 16 wait(); 17 deleteLater(); 18 }
3、QControlSocketObj类
1 #include "qcontrolsocketobj.h" 2 #include <QDebug> 3 #include <QThread> 4 5 QControlSocketObj::QControlSocketObj(qintptr socketDescriptor,QObject *parent) : QObject(parent) 6 { 7 m_ControlSocket = new QTcpSocket; 8 m_ControlSocket->setSocketDescriptor(socketDescriptor); 9 10 connect(m_ControlSocket,SIGNAL(readyRead()),this,SLOT(dataReceived())); 11 12 qDebug()<<"QControlSocketObj Construct Function threadid:"<<QThread::currentThreadId(); 13 } 14 15 void QControlSocketObj::dataReceived() 16 { 17 qDebug()<<"QControlSocketObj dataReceived Function threadid:"<<QThread::currentThreadId(); 18 }
显示结果如下:
这是连接的客户端,连接了2个tcp客户端,连接上了以后,给服务器随便发送了些文字。
2、应用程序输出结果。
基本想法达到了,还是有几个地方值得注意。QControlThread的构造函数执行在主线程中,QControlSocketObj的构造函数也执行在主线程中。
QObject::MoveToThread的官方说明是:
Changes the thread affinity for this object and its children. The object cannot be moved if it has a parent. Event processing will continue in the targetThread.
QControlThread对象和QControlSocketObj对象都是在QListenSocket类中被构造的,所以他们的构造函数会在主线程中被执行。
QThread所表示的线程是其成员函数Run执行的代码。run的默认处理就是做消息的接收与处理。