1. 程式人生 > 其它 >如何將Qt的QTcpserver和其他socket事件放到子執行緒中去處理

如何將Qt的QTcpserver和其他socket事件放到子執行緒中去處理

技術標籤:Qtqtc++多執行緒網路伺服器

如何將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那麼這兩個物件所有資源就應該是屬於主執行緒的,除了老生常談的同步與互斥問題,主執行緒還應該對這兩個物件全權負責,這樣程式碼寫起來才不會亂,諸如在子執行緒中釋放了某個主執行緒的中構造的物件,然後主執行緒不知道又去訪問了此類的問題才會大大減少。
可能我說的不對,但是學習本來就是不斷修正知識模型的過程,歡迎各位看官指點一二。