赞
踩
最近写一个项目用到了服务器开启多线程,阅博客无数,奈何没有理解精髓,致晚上梦见自己写出来了。次日,奋笔疾书,埋头苦学,最后终于写出来了。现在总结一下。
服务器多线程需要用到: QTcpServer QTcpSocket QThread
QTcpServer 最主要的一个incomingConnection虚函数的重写
当QTcpServer监听到一个可用的连接时,会有一个socket descriptor 。
也就是说服务端监听到一个连接,就会有一个唯一的描述标识,依据这个标识会创建一个QTcpSocket。
QTcpSocket
myclient.h
#ifndef MYCLICENT_H #define MYCLICENT_H #include <QTcpSocket> #include <QObject> class MyClicent : public QTcpSocket { Q_OBJECT public: explicit MyClicent(qintptr socketdesc,QObject *parent = nullptr); void on_connected(); QByteArray arraybuffer; signals: public slots: void on_discon(); }; #endif // MYCLICENT_H
myclient.cpp
//处理收发,监听等 #include "myclicent.h" #include <QDataStream> #include <QDebug> #include <QString> MyClicent::MyClicent(qintptr socketdesc,QObject *parent) : QTcpSocket(parent) { this->setSocketDescriptor(socketdesc); // this->on_connected(); connect(this,&MyClicent::readyRead,this,&MyClicent::on_connected); this->connect(this,SIGNAL(disconnected()),this,SLOT(on_discon())); } void MyClicent::on_connected() { qDebug()<<"send success!"; QByteArray array = this->readAll();//QByteArray转浮点数据 arraybuffer.append(array); qDebug()<<arraybuffer.size()<<array.size(); if(arraybuffer.size()<3360000*4) return; float * data_2 = new float[3360000]; memcpy(data_2,arraybuffer.data(),3360000*4); for(int i = 0;i<10;i++) { qDebug()<<"data[1]:"<<data_2[i]<<endl; } } void MyClicent::on_discon() { qDebug()<<"disconnect!"; }
MyServer.h
#ifndef MYSERVER_H #define MYSERVER_H #include <QTcpServer> #include <QObject> #include "mythread.h" #include "myclicent.h" class MyServer : public QTcpServer { Q_OBJECT public: explicit MyServer(QObject *parent = nullptr); MyClicent *client; signals: protected: virtual void incomingConnection(qintptr socketDescriptor); public slots: }; #endif // MYSERVER_H
MyServer.cpp
#include "myserver.h" #include <QMessageBox> MyServer::MyServer(QObject *parent) : QTcpServer(parent) { } void MyServer::incomingConnection(qintptr socketDescriptor) { QMessageBox::about(0,"提示","有新连接"); client = new MyClicent(socketDescriptor); MyThread * thread=new MyThread(socketDescriptor,0); connect(thread, &MyThread::finished, [&]{ qDebug() << "thread is over"; }); connect(thread, &MyThread::finished, &MyThread::deleteLater); thread->start(); }
MyThread.h
#include "myserver.h" #include <QMessageBox> MyServer::MyServer(QObject *parent) : QTcpServer(parent) { } void MyServer::incomingConnection(qintptr socketDescriptor) { QMessageBox::about(0,"提示","有新连接"); client = new MyClicent(socketDescriptor); MyThread * thread=new MyThread(socketDescriptor,0); connect(thread, &MyThread::finished, [&]{ qDebug() << "thread is over"; }); connect(thread, &MyThread::finished, &MyThread::deleteLater); thread->start(); }
MyThread.cpp
#include "mythread.h" MyThread::MyThread(qintptr socketdesc,QObject *parent) : QThread(parent) { qDebug()<<"QThread is still"; this->ptr=socketdesc; } void MyThread::run() { qDebug()<<"开始新线程"; MyClicent * socket=new MyClicent(this->ptr,0); socket->waitForBytesWritten(); this->exec(); }
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QTcpSocket> #include <QTcpServer> #include <QWidget> #include <QHostAddress> #include "myserver.h" namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; // QTcpServer *tcpserver = NULL; // QTcpSocket *tcpsocket = NULL; MyServer *server; }; #endif // WIDGET_H
widget.cpp
//服务器的步骤和函数 //1.建立套接字 2.监听listen(QHostAddress,888) 3.建立连接newConnection //4.netPendingconnection,peerAdress,peerPort 5.建立连接不断监听readyread //6.QByteArray array = tcpsocket->readAll(); //参考连接:https://blog.csdn.net/qqwangfan/article/details/78271110?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1 //https://blog.csdn.net/wayrboy/article/details/83108755 #include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); server = new MyServer(this); //监听,建立连接套接字 this->server->listen(QHostAddress::Any,8888); } Widget::~Widget() { delete ui; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。