用QT实现一个模型交互的网络请求

时间:2022-12-30 21:54:11

最近,我接收到了一个项目需求,具体内容如下:

具体要求:
1.交付给我程序的源代码即可,因为我要集成到我的大软件中,要求采用C++和QT开发;
2.程序首先检测当前用户环境有没有联网,如果没有联网直接结束;
3.客户端 post数据的时候,传3个参数:
参数1:用户名:用户计算机名+硬盘序列号
参数2:用户名经过md5加密(加salt)算法得到的加密后字符串
参数3:用户上传的模型文件。
4.获取到后台接口返回的stl格式文件后,将stl格式文件保存到本地文件夹下面。
5.如果转换不成功,后台服务接口会返回失败的代码,需要程序将代码cout出来。

图片版:

用QT实现一个模型交互的网络请求

 因为自己以前正好做过相关内容模块(我开发过一款基于QT的集群管理系统,实现多节点并行处理数据),于是按照要求开发了这个接口,测试界面如下:

用QT实现一个模型交互的网络请求

 这里分享出关键源代码,供有需要的童鞋参考吧。

//author:autumoon
//联系邮箱:9506#163.com
//日期:2022-12-29 
#pragma once
#include <QObject>

class STPInterface : public QObject
{
    Q_OBJECT

public:
    STPInterface(QObject *parent = Q_NULLPTR);

    //获取当前用户名
    static QString GetCurrentUserName();
    //获取硬盘序列号
    static QString GetHardDiskSerialNumber();
    //计算字符串md5
    static QString CalcStringMd5(const QString& strInputString);

    static QByteArray PrepareData(const QString& strUserName, const QString& strDiskSerial, const QString& strSTLFilePath);

    //发送网络请求
    int RequestStlFile(const QUrl& qUrl, const QByteArray& ba);
    void SetSaveStlFilePath(const QString& stpFilePath) { m_strStpFilePath = stpFilePath; }

private slots:
    void SaveRequestData(bool bSuccess, const QByteArray& baReply);

private:
    QString m_strStpFilePath;
};

下面是源代码实现:

//author:autumoon
//联系邮箱:9506#163.com
//日期:2022-12-29 
#include "STPInterface.h"
#include <QProcess>
#include <QCryptographicHash>
#include <QFile>

//json
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonValue>

#include "HttpRequest.h"

STPInterface::STPInterface(QObject *parent)
    : QObject(parent)
{
}

QString STPInterface::GetCurrentUserName()
{
    QString name = qgetenv("USER");
    if (name.isEmpty())
        name = qgetenv("USERNAME");
    return name;
}

QString STPInterface::GetHardDiskSerialNumber()
{
    QProcess p;

    p.start("wmic diskdrive where index=0 get serialnumber");  //获取硬盘序号
    p.waitForStarted();
    p.waitForFinished();
    QString DiskNum = QString::fromLocal8Bit(p.readAllStandardOutput());
    DiskNum = DiskNum.remove("SerialNumber").trimmed();		//除去前缀
    p.close();//注意释放资源

    return DiskNum;
}

QString STPInterface::CalcStringMd5(const QString& strInputString)
{
    QString str = strInputString;
    //返回哈希数据,第二个参数是采用何种算法
    QByteArray hashData = QCryptographicHash::hash(str.toLocal8Bit(), QCryptographicHash::Md5);
    //返回字节数组的十六进制编码,编码使用数字0-9和字母a-f
    str = hashData.toHex();

    return str;
}

QByteArray STPInterface::PrepareData(const QString& strUserName, const QString& strDiskSerial, const QString& strSTPFilePath)
{
    QFile readFile(strSTPFilePath);
    if (!readFile.open(QIODevice::ReadOnly))
    {
        return QByteArray();
    }

    QByteArray baFile = readFile.readAll();

    QJsonObject jo;

    QString strUserNameDiskSerial = strUserName + "_" + strDiskSerial;
    QString strUserNameMd5 = CalcStringMd5(strUserName);
    jo.insert("username_diskserial", QJsonValue(strUserNameDiskSerial.toUtf8().data()));
    jo.insert("usernamemd5", QJsonValue(strUserNameMd5.toUtf8().data()));
    jo.insert("stpfiledata", QJsonValue(baFile.data()));

    QByteArray baPostData = QJsonDocument(jo).toJson();

    return baPostData;
}

int STPInterface::RequestStlFile(const QUrl& qUrl, const QByteArray& ba)
{
    HttpRequest hr;

    connect(&hr, &HttpRequest::reply_data, this, &STPInterface::SaveRequestData);

    if (hr.RequestHttpUrl(qUrl.toString(), HTTP_POST, ba, 10000) < 0)
    {
        return -1;
    }

    return 0;
}

void STPInterface::SaveRequestData(bool bSuccess, const QByteArray& baReply)
{
    if (bSuccess)
    {
        QFile file(m_strStpFilePath);
        if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            file.write(baReply);
            file.close();
        }
    }
}

经过测试,初步具备模型交互的功能,具体细节实现可能需要进一步修改。

欢迎交流与讨论。