一.多线程的使用:
继承QThread类,重写protected: void run();函数,则此run函数即为多线程将执行的函数,UI类组合此类,调用start()函数即开启此线程,并执行run函数
//.h
class test1 : public QThread //!!
{
Q_OBJECT
public:
explicit test1(QObject *parent = nullptr);
signals:
public slots:
protected:
void run(); //!!
void read();
};
//.cpp
void test1::run()
{
qDebug()<<QThread::currentThreadId()<<endl<<"threadnow";
read();
}
void test1::read()
{
qDebug()<<QThread::currentThreadId()<<endl<<"threadnow";
}
//.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
test1 *threadtest; //!!
private slots:
void on_button_begin_clicked();
private:
Ui::MainWindow *ui;
};
//.cpp
void MainWindow::on_button_begin_clicked()
{
qDebug()<<QThread::currentThreadId()<<endl;
threadtest=new test1;
threadtest->start(); //!!
}
二.多线程在TCP通信中的应用
基本流程:
1.新建一个类继承自QTcpServer,重写 protected: void incomingConnection(qintptr socketDescriptor);
当有一个连接到来时将自动调用此函数,所以应在此函数中创建线程。
2.新建一个类继承自QThread,重写 protected: void run();
,将此类组合进 1 中的类,则当 1 中的类使用 start()
后将自动调用 run()
函数
3.在 2 的run()
函数中使用waitForReadyRead()
进行阻塞,从而获取数据
4.改进 3 的接收方式,新建一个类继承自QTcpSocket
,在其中使用readyRead()
与槽函数进行信息接收与发送
//myserver.h
#include <QTcpSocket>
#include <QTcpServer>
#include "serverthread.h"
class myserver:public QTcpServer
{
public:
myserver();
protected:
void incomingConnection(qintptr socketDescriptor);
};
//myserver.cpp
#include "myserver.h"
myserver::myserver()
{}
void myserver::incomingConnection(qintptr socketDescriptor)
{
qDebug()<<"New Connect is connect"<<socketDescriptor;
ServerThread * thread=new ServerThread();
thread->write_ptr(socketDescriptor);
thread->start();
}
//serverthread.h
#include <QThread>
#include <QTcpSocket>
#include <QTcpServer>
class ServerThread:public QThread
{
public:
ServerThread();
qintptr ptr;
QTcpSocket * socket;
void write_ptr(qintptr p);
protected:
void run();
};
//serverthread.cpp
#include "serverthread.h"
ServerThread::ServerThread()
{}
void ServerThread::write_ptr(qintptr p)
{
ptr=p;
}
void ServerThread::run()
{
socket=new QTcpSocket();
socket->setSocketDescriptor(ptr);//客户端的初始化
if(socket->waitForConnected(10000)){
qDebug()<<"Connect Success";
}
else{
qDebug()<<"Connect Fail";
}
QByteArray data;
forever {
if (socket->waitForReadyRead())
{
qDebug()<<QThread::currentThreadId();
data = socket->readAll();
qDebug()<<data;
}
else {
qDebug()<<"none";
break;
}
}
}
//mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
//mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{
qDebug()<<QThread::currentThreadId();
myserver * server;
server=new myserver();
server->listen(QHostAddress::AnyIPv4,8888);
}
//mysocket.h
#include <QTcpSocket>
class mysocket:public QTcpSocket
{
Q_OBJECT
public:
mysocket();
public slots:
void recvData(void);
private:
int m_sockDesc;
};
//mysocket.cpp
mysocket::mysocket()
{
connect(this, SIGNAL(readyRead()), this, SLOT(recvData()));
}
void mysocket::recvData()
{
QByteArray buffer = this->readAll();
if(!buffer.isEmpty())
{//处理接收到的数据
qDebug()<<buffer;
QString data="send";
this->write(data.toLatin1());
}
}
//更改代码
void ServerThread::run()
{
socket=new mysocket;
socket->setSocketDescriptor(ptr);//客户端的初始化
if(socket->waitForConnected(10000)){
qDebug()<<"Connect Success";
}
else{
qDebug()<<"Connect Fail";
}
this->exec();
}
三.借鉴出处
1.Qt Socket 多线程操作
2.Qt TCP通信,多线程服务器端