多终端多线程数据入库架构和代码(Qt5.9.5 MySQL)

资源连接:https://download.csdn.net/download/smalbig/12302458
未经允许请勿转载。

架构和实现:每当有一个新的入库请求时,服务器新建一个线程,线程内new一个QTcpSocket用来接收终端的数据,线程内新建一个数据库连接。在服务器内实现互不干扰,独立入库的功能。
线程安全,工业信息采集实际项目代码,单终端每秒500条类似“22 33 44 55”格式的数据,多终端则倍增,最大速度受制于处理器。
关键代码:
响应新连接类

class FortuneServer : public QTcpServer
{
    Q_OBJECT
public:
    FortuneServer(QObject *parent = 0);
protected:
    void incomingConnection(qintptr socketDescriptor) override;
};

响应新连接实现关键代码:重写了QTcpServer中的incomingConnection函数,当有新tcp连接时该函数被调用。在该函数中new了一个FortuneThread类的线程,该线程内用来执行获取终端传来的消息,并把消息入库的操作。

FortuneServer::FortuneServer(QObject *parent)
    : QTcpServer(parent)
{
}

int linkNum = 0;//数据库连接名自增
void FortuneServer::incomingConnection(qintptr socketDescriptor){
    FortuneThread *thread = new FortuneThread(socketDescriptor, "",QString::number(linkNum), this);
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    thread->start();
    linkNum += 1;
}

线程类

#ifndef FORTUNETHREAD_H
#define FORTUNETHREAD_H
#include <iostream>
#include <QtSql>
#include <QThread>
#include <QTcpSocket>
#include <QtNetwork>
#include <QMutex>
//! [0]
#pragma execution_character_set("utf-8")
class FortuneThread : public QThread
{
    Q_OBJECT
public:
 FortuneThread(int socketDescriptor, const QString &fortune,QString LINKNUM, QObject *parent);
    void run() override;
signals:
    void error(QTcpSocket::SocketError socketError);

private:
    QMutex mutex;
    QTcpSocket *tcpSocket;
    int socketDescriptor;
    bool m_stop = false;
};

线程实现:

#include "fortunethread.h"

#include <QtNetwork>
#include <Qdir>
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QTextCodec>
#include <QString>
#include <QDateTime>
#include <QQueue>
//! [0]
//extern QSqlDatabase db;
QStringList resultList;
bool dbopen;
int num = 0;
extern int linkNum;
QQueue<QByteArray> queue;
FortuneThread::FortuneThread(int socketDescriptor, const QString &fortune, QString LINKNUM,QObject *parent)
    : QThread(parent), socketDescriptor(socketDescriptor), text(fortune)
{
    SingleLINKNUM = LINKNUM;
}

void FortuneThread::run()
{

    tcpSocket = new QTcpSocket();
    if (!tcpSocket->setSocketDescriptor(socketDescriptor)) {
        emit error(tcpSocket->error());
        return;
    }
    //事件循环
    msleep(500);//可有效缓解并发链接问题
    eventloop = new QEventLoop();
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(onreadyread()),Qt::DirectConnection);
    connect(tcpSocket,SIGNAL(disconnected()),this,SLOT(ondisconnect()),Qt::DirectConnection);
    eventloop->exec();

    linkNum -= 1;
    //断开一次链接则链接数减一,给新的连接留出位置。
。
。
。
。
。
}
void FortuneThread::onreadyread(){
    //
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL",SingleLINKNUM);//增加新连接
    db.setHostName("localhost");
    db.setDatabaseName("world");
    db.setUserName("root");
    db.setPassword("1234");
    。
    。
    。
    。
    。
    。
    。
    
    QSqlQuery querysql(db);//QSqlQuery querysql(db),记住加上数据库名称

	。
	。
	。
	。
	。
	。

    inmsg = tcpSocket->readAll();
    QString msg = inmsg.data();
    querysql.prepare("insert into city values(?,?,?,?,?);");
                        if(bindVals.size()>3){
                             querysql.bindValue(1,bindVals[1]);
                             querysql.bindValue(2,bindVals[2]);
                             querysql.bindValue(3,bindVals[3]);
                             querysql.bindValue(4,datetime);

                        }
                          querysql.exec();
                     }
                }
                }
                mutex.unlock();
        }else{
            db.open();
        }
    }
    //
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值