QT多线程服务器Tcp

最近写一个项目用到了服务器开启多线程,阅博客无数,奈何没有理解精髓,致晚上梦见自己写出来了。次日,奋笔疾书,埋头苦学,最后终于写出来了。现在总结一下。
服务器多线程需要用到: QTcpServer QTcpSocket QThread
QTcpServer 最主要的一个incomingConnection虚函数的重写

  • 自定义一个client类继承于QTcpSocket :用于解析和发送数据
  • 自定义一个server类继承于QTcpSwever:重写虚函数void incomingConnection(),用于接收客户端的连接(取代没有线程的newconnect)
  • 自定义一个thread继承于QThread:主要用于处理client里面的数据,重写void run()
  • widget主要用于端口的连接等

当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;
}


  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值