如何將Qt的QTcpserver和其他socket事件放到子執行緒中去處理
阿新 • • 發佈:2021-02-05
如何將Qt的QTcpserver和其他socket事件放到子執行緒中去處理
話不多說先看效果是不是你想要的
上程式碼
mian.cpp
#include <QCoreApplication>
#include <QMetaType>
#include <QHostAddress>
#include <QTcpSocket>
#include "MyThread.h"
Q_DECLARE_METATYPE(QHostAddress)
int main(int argc, char *argv[])
{
//這東西居然沒有被預設註冊到METATYPE中,先註冊一下
qRegisterMetaType<QHostAddress>("QHostAddress&");
qRegisterMetaType<QHostAddress>("QHostAddress");
QCoreApplication a(argc, argv) ;
new MyTread;
//列印主執行緒的地址
qDebug() << __FUNCTION__ << QThread::currentThread();
//構造測試用的客戶端
QTcpSocket * testClient = new QTcpSocket;
testClient->bind(QHostAddress("127.0.0.1"), 4444);
testClient->connectToHost("127.0.0.1", 7777);
testClient- >write("hellow\0", 7);
return a.exec();
}
Class MyThread
.h
#ifndef MYTREAD_H
#define MYTREAD_H
#include <QThread>
#include <QHostAddress>
class MyTread:public QThread
{
Q_OBJECT
public:
MyTread(QObject *parent = nullptr);
signals:
void listened(const QHostAddress address = QHostAddress::Any, quint16 port = 0);
};
#endif // MYTREAD_H
.cpp
#include "MyThread.h"
#include "MyServer.h"
MyTread::MyTread(QObject *parent) : QThread(parent)
{
MyServer * s = new MyServer;//注意,此處不要設定父物件
s->moveToThread(this);
this->start();
connect(this, &MyTread::listened, s, &MyServer::onListened);
connect(s, &MyServer::newConnection, s,&MyServer::onNewConnection);
emit listened(QHostAddress::Any, 7777);
}
Class MyServer
.h
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
class MyServer: public QTcpServer
{
Q_OBJECT
public:
MyServer(QObject *parent = nullptr);
public slots:
void onListened(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
void onNewConnection();
};
#endif // MYSERVER_H
.cpp
#include "MyServer.h"
#include <QDebug>
#include <QThread>
#include <QTcpSocket>
MyServer::MyServer(QObject *parent):QTcpServer(parent)
{
}
void MyServer::onListened(const QHostAddress &address, quint16 port)
{
this->listen(address, port);//開始監聽
qDebug() << __FUNCTION__ << QThread::currentThread();
}
void MyServer::onNewConnection()
{
QTcpSocket * sock = this->nextPendingConnection();//接受到連線
qDebug() << __FUNCTION__ << QThread::currentThread();
connect(sock, &QTcpSocket::readyRead, [=](){
//收到客戶端的訊息
qDebug() << __FUNCTION__ << QThread::currentThread() << sock->readAll().data();
});
}
後記
很多人不清楚一個概念,我開始也不知到或是說沒意識到,後來聽別人說了才意識到,就是在qt的概念裡(可能也不是qt的概念,理應如此),在哪個執行緒中構建的物件,該物件資源就屬於哪個執行緒;
如上,我在主執行緒中構建了MyThread和MyServer那麼這兩個物件所有資源就應該是屬於主執行緒的,除了老生常談的同步與互斥問題,主執行緒還應該對這兩個物件全權負責,這樣程式碼寫起來才不會亂,諸如在子執行緒中釋放了某個主執行緒的中構造的物件,然後主執行緒不知道又去訪問了此類的問題才會大大減少。
可能我說的不對,但是學習本來就是不斷修正知識模型的過程,歡迎各位看官指點一二。