Qt下对libcurl进行封装,生成SDK共享库,提供库调用的demo,和http服务器demo,支持get和post请求方式,库支持https,demo程序亲测可用

1. LibCurl的简单介绍

libcurl是一个优秀的网络请求库,其主要功能是用不同的协议连接和沟通不同的服务器,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议,同时也支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传,HTTP基本表单上传,代理,cookies,和用户认证。

2. LibCurl的编译

见我的另一篇博客:https://blog.csdn.net/linyibin_123/article/details/127574012

3. 使用LibCurl封装SDK库

采用工厂模式,类LibCurlSdk实现了公有的日志操作功能,LibCurlSdkHttp类和LibCurlSdkFTP继承于LibCurlSdk,分别实现http操作功能和ftp操作功能。同时为了不对外暴露实际的功能代码,类LibCurlSdkHttp和类LibCurlSdkFTP使用纯虚函数,即类LibCurlSdkHttp和类LibCurlSdkFTP为抽象类,实际功能由其子类HttpSdk和FtpSdk进行实现。类LibCurlSdkHttp和类LibCurlSdkFTP均支持单例模式,类LibCurlSdkHttp的SendHttpGet和SendHttpPost接口可供调用者使用自定义的url进行请求,SdkAddJob接口可让调用者根据枚举项选择某个功能进行请求,该请求会在线程池中执行。

3.1 核心代码:

libcurlsdk.h
/**************************************************************************
Copyright:My LibCurlSdk
Author: ybLin
Date:2022-11-08
Description: LibCurl SDK
**************************************************************************/
#ifndef LIBCURLSDK_H
#define LIBCURLSDK_H
#include <QObject>

#include "libcurlsdk_global.h"

//Log Level
typedef enum SDK_LOG_LEVEL
{
    LOG_LEVEL_DEBUG = 0,
    LOG_LEVEL_INFO,
    LOG_LEVEL_WARN,
    LOG_LEVEL_CRITICAL,
    LOG_LEVEL_FATAL
}SDK_LOG_LEVEL_E;

//Content-Type
typedef enum SDK_CONTENT_TYPE
{
    CONTENT_TYPE_TEXT_HTML = 0,//HTML格式
    CONTENT_TYPE_TEXT_PLAIN,//纯文本格式
    CONTENT_TYPE_TEXT_XML,//XML格式
    CONTENT_TYPE_IMAGE_GIF,//gif图片格式
    CONTENT_TYPE_IMAGE_JPEG,//jpg图片格式
    CONTENT_TYPE_IMAGE_PNG,//png图片格式
    CONTENT_TYPE_APPLICATION_XHTML_XML,//XHTML格式
    CONTENT_TYPE_APPLICATION_XML,//XML数据格式
    CONTENT_TYPE_APPLICATION_ATOM_XML,//Atom XML聚合格式
    CONTENT_TYPE_APPLICATION_JSON,//JSON数据格式
    CONTENT_TYPE_APPLICATION_PDF,//pdf格式
    CONTENT_TYPE_APPLICATION_MSWORD,//Word文档格式
    CONTENT_TYPE_APPLICATION_OCTET_STREAM,//二进制流数据
    CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED,//表单默认的提交数据的格式
    CONTENT_TYPE_MULTIPART_FORM_DATA//需要在表单中进行文件上传时,就需要使用该格式
}SDK_CONTENT_TYPE_T;

typedef struct
{
    char sIP[64];
    int nPort;
    char sUserName[64];
    char sPassword[32];
}SDK_USER_INFO_T;

typedef enum SDK_API_TYPE
{
    API_TYPE_SET_BRIGHTNESS = 0,
    API_TYPE_GET_BRIGHTNESS,
    API_TYPE_SET_IMAGEPARAMS,
    API_TYPE_GET_IMAGEPARAMS,
    API_TYPE_SET_TESTPARAM,
    API_TYPE_GET_TESTPARAM,

    API_TYPE_HTTP_MAX


}SDK_API_TYPE_E;

typedef struct
{
    int nBrightness;
    int nContrast;
    int nSaturation;
    int nSharpness;
    int nFLevel;
}IMAGE_SETTINGS_T;


///
/// \brief The LibCurlSdk class
///Common
class LIBCURLSDKSHARED_EXPORT LibCurlSdk
{
public:
    LibCurlSdk();

    //Log
    void setLogSave(bool bSave, QString sPath = "");
    void setLogLevel(SDK_LOG_LEVEL_E nLevel);
};


//Http
class LIBCURLSDKSHARED_EXPORT LibCurlSdkHttp : public QObject, public LibCurlSdk
{
Q_OBJECT
public:
    LibCurlSdkHttp();

    static LibCurlSdkHttp& getInstance();

    //Get Common API
    virtual int SendHttpGet(const QString sUrl, QString& sResponse) = 0;

    //Post Common API
    virtual int SendHttpPost(const QString sUrl, const QString sParam, const QString sHead, QString& sResponse) = 0;
    virtual int SendHttpPost(const QString sUrl, const QString sParam, SDK_CONTENT_TYPE_T nHead, QString& sResponse) = 0;

    //Api in Thread
    virtual void SdkAddJob(SDK_USER_INFO_T stUser, SDK_API_TYPE_E eCmd, void *IpcParam) = 0;

signals:
    void sig_HttpJobReturn(SDK_USER_INFO_T stUser, int eCmd, void* IpcParam, bool bSucc);
};

//Ftp 暂未实现
class LIBCURLSDKSHARED_EXPORT LibCurlSdkFTP : public QObject, public LibCurlSdk
{
public:
    LibCurlSdkFTP();

    static LibCurlSdkFTP& getInstance();

    virtual int UploadFtp(const QString sIP, const quint16 nPort, QString& sResponse) = 0;
    virtual int DownLoadFtp(const QString sIP, const quint16 nPort, QString& sResponse) = 0;
};

#endif // LIBCURLSDK_H

libcurlsdk.cpp
#include "libcurlsdk.h"
#include "httpsdk.h"
#include "ftpsdk.h"
#include "runlog.h"
#include <QDebug>

LibCurlSdk::LibCurlSdk()
{
}

/***************************
 * Log Config
 * *************************/
void LibCurlSdk::setLogSave(bool bSave, QString sPath)
{
    qDebug() << __FUNCTION__ << " sPath:" << sPath;
    if(bSave)
    {
        RunLog::Instance()->start(sPath);
    }
    else
    {
        RunLog::Instance()->stop();
    }
}

void LibCurlSdk::setLogLevel(SDK_LOG_LEVEL_E nLevel)
{
    qDebug() << __FUNCTION__ << " nLevel:" << nLevel;
    RunLog::Instance()->setLogLevel(RunLog::LOG_LEVEL(nLevel));
}

/***************************
 * Http
 * *************************/
LibCurlSdkHttp::LibCurlSdkHttp()
{
    //qRegisterMetaType<SDK_USER_INFO_T>("SDK_USER_INFO_T");
}

LibCurlSdkHttp &LibCurlSdkHttp::getInstance()
{
    static HttpSdk s_obj;
    return s_obj;
}

/***************************
 * Ftp
 * *************************/
LibCurlSdkFTP::LibCurlSdkFTP()
{
}

LibCurlSdkFTP &LibCurlSdkFTP::getInstance()
{
    static FtpSdk s_obj;
    return s_obj;
}


httpsdk.h
#ifndef HTTPSDK_H
#define HTTPSDK_H
#include "libcurlsdk.h"
#include "sdkthread.h"

#define MAX_BUF_SIZE_8    8
#define MAX_BUF_SIZE_16  16
#define MAX_BUF_SIZE_32  32
#define MAX_BUF_SIZE_64  64
#define MAX_BUF_SIZE_96  96
#define MAX_BUF_SIZE_128 128
#define MAX_BUF_SIZE_256 256
#define MAX_BUF_SIZE_512 512
#define MAX_BUF_SIZE_1024 1024
#define MAX_BUF_SIZE_2048 2048
#define MAX_BUF_SIZE_4096 4096

#define SEP_STRING "\n"

class HttpSdk : public LibCurlSdkHttp
{
public:
    HttpSdk();

    static HttpSdk& getInstance();

    //Api Run In Thread
    void SdkAddJob(SDK_USER_INFO_T stUser, SDK_API_TYPE_E eCmd, void *IpcParam);

    //Get
    //Get Common API
    int SendHttpGet(const QString sUrl, QString& sResponse);
    //Get Proper API
    int setBrightness(SDK_USER_INFO_T stUser, void* pParam);
    int getBrightness(SDK_USER_INFO_T stUser, void* pParam);
    int setImageParams(SDK_USER_INFO_T stUser, void* pParam);
    int getImageParams(SDK_USER_INFO_T stUser, void* pParam);

    //Post Common API
    int SendHttpPost(const QString sUrl, const QString sParam, const QString sHead, QString& sResponse);
    int SendHttpPost(const QString sUrl, const QString sParam, SDK_CONTENT_TYPE_T nHead, QString& sResponse);
    //Post Proper API
    int setTestParam(SDK_USER_INFO_T stUser, void* pParam);
    int getTestParam(SDK_USER_INFO_T stUser, void* pParam);

private:
    QString m_sUser;
    QString m_sPwd;

    SDKThread *m_sdkT;

};

#endif // HTTPSDK_H

httpsdk.cpp
#include "httpsdk.h"
#include "curlsdk.h"
#include "runlog.h"
#include <QDateTime>
#include <QJsonParseError>
#include <QJsonObject>

/
/**********************************
 * Common API
 * ********************************/
static int MySscanf(const char *pText, const char *pRegExp, const char sSep[1],
                    char *pResult, int nResultLen)
{
    int i = 0;
    size_t nStart = strlen(pRegExp);
    const char *pStr = strstr(pText, pRegExp);
    if(!pStr)
        return -1;
    for(; i < (int)strlen(pStr); i++)
    {
        if(pStr[nStart+i] == sSep[0])
            break;
        if(i+1 > nResultLen)
            break;
        pResult[i] = pStr[nStart+i];
    }
    pResult[i] = '\0';
    return i;
}

int GetResponseVal(QString sKey, const char *pResponse, char *pVal, int nValLen)
{
    QByteArray ba = sKey.toLatin1();
    char *pCh = ba.data();

    char sFilter[MAX_BUF_SIZE_128] = {0};
    snprintf(sFilter, sizeof(sFilter), "OK %s=", pCh);
    if(MySscanf(pResponse, sFilter, SEP_STRING, pVal, nValLen) != -1)
    {
        return 0;
    }
    else
    {
        return -1;
    }
}

void GetResponseIntVal(QString skey, const char *pResponse, int *pVal)
{
    QByteArray ba = skey.toLatin1();
    char *ch = ba.data();

    char sVal[MAX_BUF_SIZE_4096] = {0};
    char sFilter[MAX_BUF_SIZE_128] = {0};
    snprintf(sFilter, sizeof(sFilter), "OK %s=", ch);
    if(MySscanf(pResponse, sFilter, SEP_STRING, sVal, sizeof(sVal)) != -1)
    {
         *pVal = atoi(sVal);
    }
}

QString GetContentType(SDK_CONTENT_TYPE_T nHead)
{
    QString sContentType;
    switch(nHead)
    {
        case CONTENT_TYPE_TEXT_HTML:
            sContentType = "Content-type:text/html";
        break;
        case CONTENT_TYPE_TEXT_PLAIN:
            sContentType = "Content-type:text/plain";
        break;
        case CONTENT_TYPE_TEXT_XML:
            sContentType = "Content-type:text/xml";
        break;
        case CONTENT_TYPE_IMAGE_GIF:
            sContentType = "Content-type:image/gif";
        break;
        case CONTENT_TYPE_IMAGE_JPEG:
            sContentType = "Content-type:image/jpeg";
        break;
        case CONTENT_TYPE_IMAGE_PNG:
            sContentType = "Content-type:image/png";
        break;
        case CONTENT_TYPE_APPLICATION_XHTML_XML:
            sContentType = "Content-type:application/xhtml+xml";
        break;
        case CONTENT_TYPE_APPLICATION_XML:
            sContentType = "Content-type:application/xml";
        break;
        case CONTENT_TYPE_APPLICATION_ATOM_XML:
            sContentType = "Content-type:application/atom+xml";
        break;
        case CONTENT_TYPE_APPLICATION_JSON:
            sContentType = "Content-type:application/json";
        break;
        case CONTENT_TYPE_APPLICATION_PDF:
            sContentType = "Content-type:application/pdf";
        break;
        case CONTENT_TYPE_APPLICATION_MSWORD:
            sContentType = "Content-type:application/msword";
        break;
        case CONTENT_TYPE_APPLICATION_OCTET_STREAM:
            sContentType = "Content-type:application/octet-stream";
        break;
        case CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED:
            sContentType = "Content-type:application/x-www-form-urlencoded";
        break;
        case CONTENT_TYPE_MULTIPART_FORM_DATA:
            sContentType = "Content-type:multipart/form-data";
        break;
    default:
        sContentType = "Content-type:text/plain";
        break;
    }
    return sContentType;
}

///

HttpSdk::HttpSdk() :
    m_sUser("admin"),m_sPwd("123456")
{
    m_sdkT = &SDKThread::instance();
}

HttpSdk &HttpSdk::getInstance()
{
    static HttpSdk s_obj;
    return s_obj;
}

/**********************************
 * Http:
 * Api Run In Thread
 * ********************************/
void HttpSdk::SdkAddJob(SDK_USER_INFO_T stUser, SDK_API_TYPE_E eCmd, void *IpcParam)
{
    m_sdkT->SDKAddJob(stUser, eCmd, IpcParam);
}

/**********************************
 * Http:
 * Get Common API
 * URL:http://127.0.0.1:8080/my.rq?setbrightnessval=50
 *     http://127.0.0.1:8080/my.rq?getparam=brightnessval
 * ********************************/
int HttpSdk::SendHttpGet(const QString sUrl, QString &sResponse)
{
    string strResponse;

    if(CurlSdk::getInstance().HttpGet(sUrl.toStdString(), strResponse) == 0)
    {
        sResponse = QString::fromStdString(strResponse);
        qDebug() << "sResponse:" << sResponse;
        if(sResponse.contains("OK"))
        {
            QString msg =  QString("Current Time: %1  Http Send:%2 Success.") \
                    .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss:zzz")) \
                    .arg(sUrl);
            qInfo() << msg;

            return 0;
        }
    }
    QString msg = QString("Current Time: %1  Http Send:%2 Fail.") \
            .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss:zzz")) \
            .arg(sUrl);
    qWarning() << msg;

    return -1;
}

/**********************************
 * Http:
 * Set Brightness (Get)
 * ********************************/
int HttpSdk::setBrightness(SDK_USER_INFO_T stUser, void* pParam)
{
    int *nVal = (int*)pParam;

    QString sUrl;
    if(strlen(stUser.sUserName) == 0 || strlen(stUser.sPassword) == 0)
    {
        sUrl = QString("http://%1:%2/my.rq?module=imageconf&setbrightnessval=%5")\
                    .arg(stUser.sIP).arg(stUser.nPort).arg(*nVal);
    }
    else
    {
        sUrl = QString("http://%1:%2@%3:%4/my.rq?module=imageconf&setbrightnessval=%5").arg(stUser.sUserName)\
                    .arg(stUser.sPassword).arg(stUser.sIP).arg(stUser.nPort).arg(*nVal);
    }

    QString sResponse;
    return SendHttpGet(sUrl, sResponse);
}

/**********************************
 * Http:
 * Get Brightness (Get)
 * ********************************/
int HttpSdk::getBrightness(SDK_USER_INFO_T stUser, void* pParam)
{
    int *nVal = (int*)pParam;

    QString sUrl;
    if(strlen(stUser.sUserName) == 0 || strlen(stUser.sPassword) == 0)
    {
        sUrl = QString("http://%1:%2/my.rq?getparam=brightnessval")\
                    .arg(stUser.sIP).arg(stUser.nPort);
    }
    else
    {
        sUrl = QString("http://%1:%2@%3:%4/my.rq?getparam=brightnessval").arg(stUser.sUserName).arg(stUser.sPassword)\
                    .arg(stUser.sIP).arg(stUser.nPort);
    }

    const QString sKey = "brightnessval";
    QString sResponse;
    char strResVal[MAX_BUF_SIZE_512];

    if(SendHttpGet(sUrl, sResponse) == 0)
    {
        std::string strResponse = sResponse.toStdString();

        if(GetResponseVal(sKey, strResponse.data(), strResVal, sizeof(strResVal)) == 0)
        {
            *nVal = QString(QLatin1String(strResVal)).toInt();
            return 0;
        }
    }
    return -1;
}

/**********************************
 * Http:
 * Set Image Params (Get)
 * ********************************/
int HttpSdk::setImageParams(SDK_USER_INFO_T stUser, void *pParam)
{
    IMAGE_SETTINGS_T *pImageParam = (IMAGE_SETTINGS_T *)pParam;
    if(pImageParam == nullptr)
        return -1;

    QString sUrl;
    if(strlen(stUser.sUserName) == 0 || strlen(stUser.sPassword) == 0)
    {
        sUrl = QString("http://%1:%2/my.rq?module=imageconf&setbrightnessval=%5&setcontrastval=%6&setsaturationval=%7&setsharpnessval=%8&setnflevelval=%9")\
                .arg(stUser.sIP).arg(stUser.nPort).arg(pImageParam->nBrightness)\
                .arg(pImageParam->nContrast).arg(pImageParam->nSaturation)\
                .arg(pImageParam->nSharpness).arg(pImageParam->nFLevel);

    }
    else
    {
        sUrl = QString("http://%1:%2@%3:%4/my.rq?module=imageconf&setbrightnessval=%5&setcontrastval=%6&setsaturationval=%7&setsharpnessval=%8&setnflevelval=%9")\
                .arg(stUser.sUserName).arg(stUser.sPassword).arg(stUser.sIP) \
                .arg(stUser.nPort).arg(pImageParam->nBrightness)\
                .arg(pImageParam->nContrast).arg(pImageParam->nSaturation)\
                .arg(pImageParam->nSharpness).arg(pImageParam->nFLevel);
    }

    QString sResponse;
    return SendHttpGet(sUrl, sResponse);
}

/**********************************
 * Http:
 * Get Image Params (Get)
 * ********************************/
int HttpSdk::getImageParams(SDK_USER_INFO_T stUser, void *pParam)
{
    IMAGE_SETTINGS_T *pImageParam = (IMAGE_SETTINGS_T *)pParam;
    if(!pImageParam)
        return -1;

    QString sUrl;
    if(strlen(stUser.sUserName) == 0 || strlen(stUser.sPassword) == 0)
    {
        sUrl = QString("http://%1:%2/my.rq?getparam=brightnessval&getparam=contrastval&getparam=saturationval"\
                               "&getparam=sharpnessval&getparam=nflevelval")\
                                .arg(stUser.sIP).arg(stUser.nPort);
    }
    else
    {
        sUrl = QString("http://%1:%2@%3:%4/my.rq?getparam=brightnessval&getparam=contrastval&getparam=saturationval"\
                               "&getparam=sharpnessval&getparam=nflevelval")\
                .arg(stUser.sUserName).arg(stUser.sPassword).arg(stUser.sIP).arg(stUser.nPort);
    }

    const QString sKey = "brightnessval";
    QString sResponse;
    int nValue;

    if(SendHttpGet(sUrl, sResponse) == 0)
    {
        std::string strResponse = sResponse.toStdString();

        GetResponseIntVal("brightnessval", strResponse.data(), &nValue);
        pImageParam->nBrightness = nValue;

        GetResponseIntVal("contrastval", strResponse.data(), &nValue);
        pImageParam->nContrast = nValue;

        GetResponseIntVal("saturationval", strResponse.data(), &nValue);
        pImageParam->nSaturation = nValue;

        GetResponseIntVal("sharpnessval", strResponse.data(), &nValue);
        pImageParam->nSharpness = nValue;

        GetResponseIntVal("nflevelval", strResponse.data(), &nValue);
        pImageParam->nFLevel = nValue;

        return 0;
    }
    return -1;
}

/**********************************
 * Http:
 * Post Common API
 * Url:http://127.0.0.1:8080
 * Param:/setparam=50
 *       /getparam=testparam
 * Header:Content-type:application/json
 * ********************************/
int HttpSdk::SendHttpPost(const QString sUrl, const QString sParam, const QString sHead, QString& sResponse)
{
    string strResponse;

    if(CurlSdk::getInstance().HttpPost(sUrl.toStdString(), sParam.toStdString(), sHead.toStdString(), strResponse) == 0)
    {
        sResponse = QString::fromStdString(strResponse);
        return 0;
    }
    return -1;
}

int HttpSdk::SendHttpPost(const QString sUrl, const QString sParam, SDK_CONTENT_TYPE_T nHead, QString &sResponse)
{
    QString sHead = GetContentType(nHead);
    string strResponse;

    if(CurlSdk::getInstance().HttpPost(sUrl.toStdString(), sParam.toStdString(), sHead.toStdString(), strResponse) == 0)
    {
        sResponse = QString::fromStdString(strResponse);
        return 0;
    }
    return -1;
}

/**********************************
 * Http:
 * Set Test Param (Post)
 * ********************************/
int HttpSdk::setTestParam(SDK_USER_INFO_T stUser, void *pParam)
{
    QString sHead = GetContentType(CONTENT_TYPE_APPLICATION_JSON);
    string strResponse;

    int *nVal = (int*)pParam;
    QString sUrl = QString("http://%1:%2").arg(stUser.sIP).arg(stUser.nPort);
    QString sParam = QString("/setparam=%1").arg(*nVal);

    if(CurlSdk::getInstance().HttpPost(sUrl.toStdString(), sParam.toStdString(), sHead.toStdString(), strResponse) == 0)
    {
        return 0;
    }
    return -1;
}

/**********************************
 * Http:
 * Get Test Param (Post)
 * ********************************/
int HttpSdk::getTestParam(SDK_USER_INFO_T stUser, void *pParam)
{
    int *pVal = (int*)pParam;

    QString sHead = GetContentType(CONTENT_TYPE_APPLICATION_JSON);
    string strResponse;
    QString sUrl = QString("http://%1:%2").arg(stUser.sIP).arg(stUser.nPort);
    QString sParam = "/getparam=testparam";
    QString sResponse;
    const QString sKey = "param";

    if(CurlSdk::getInstance().HttpPost(sUrl.toStdString(), sParam.toStdString(), sHead.toStdString(), strResponse) == 0)
    {
        sResponse = QString::fromStdString(strResponse);

        QByteArray byteArray = sResponse.toLatin1();
        QJsonParseError jsonError;
        // 转化为 JSON 文档
        QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError);

        // 解析未发生错误
        if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError))
        {
            if (doucment.isObject())
            {
                // JSON 文档为对象
                QJsonObject object = doucment.object();  // 转化为对象
                if (object.contains("param"))
                {  // 包含指定的 key
                    QJsonValue value = object.value("param");  // 获取指定 key 对应的 value
                    if (value.isDouble())
                    {
                        int nVal = value.toVariant().toInt();
                        qDebug() << "Param : " << nVal;

                        *pVal = nVal;
                        return 0;
                    }
                }
            }
        }
    }

    return -1;
}
sdkthread.h
/**************************************************************************
Copyright:IVS Camera
Author: ybLin
Date:2022-11-8
Description:SDK Thread
**************************************************************************/
#ifndef SDKTHREAD_H
#define SDKTHREAD_H

#include <QObject>
#include "sdktask.h"

class SDKThread : public QObject
{
public:
    static SDKThread& instance();
    virtual ~SDKThread();
    SDKTask *m_psdktaskT;
    void SDKAddJob(SDK_USER_INFO_T stUser, int eCmd, void* IpcParam);

private:
    explicit SDKThread(QObject *parent = nullptr);
};

#endif // SDKTHREAD_H

sdkthread.cpp
/**************************************************************************
Copyright:My LibCurlSdk
Author: ybLin
Date:2022-11-8
Description:Thread Function
**************************************************************************/

#include "sdkthread.h"
#include <QThreadPool>

SDKThread::SDKThread(QObject *parent) : QObject(parent)
{
    QThreadPool::globalInstance()->setMaxThreadCount(128);
}

SDKThread &SDKThread::instance()
{
    static SDKThread s_obj;
    return s_obj;
}

SDKThread::~SDKThread()
{
}

void SDKThread::SDKAddJob(SDK_USER_INFO_T stUser, int eCmd, void *IpcParam)
{
    m_psdktaskT = new SDKTask(nullptr, eCmd, IpcParam, stUser);
    if(m_psdktaskT)
    {
        QThreadPool::globalInstance()->start(m_psdktaskT);
    }
}

sdktask.h
#ifndef SDKTASK_H
#define SDKTASK_H
#include <QObject>
#include <QMutex>
#include <QRunnable>
#include "libcurlsdk.h"

//QT_FORWARD_DECLARE_CLASS(SDKThread)

class SDKTask: public QObject, public QRunnable
{
    Q_OBJECT
public:
    SDKTask(QObject *parent, int eCmd, void *param, SDK_USER_INFO_T& stUser);
    virtual ~SDKTask();
    void run();
private:
    int m_nCmd;
    void* m_pParam;
    SDK_USER_INFO_T m_stUser;

signals:
    void sig_httptaskreturn(SDK_USER_INFO_T pUser, int eCmd, void* IpcParam, bool bSucc);

};

#endif // SDKTASK_H


sdktask.cpp
#include "sdktask.h"
#include "httpsdk.h"
#include <QDebug>

SDKTask::SDKTask(QObject *parent, int eCmd, void *param, SDK_USER_INFO_T& stUser)
    : QObject(parent),
      m_nCmd(eCmd), m_pParam(param), m_stUser(stUser)
{
    this->setAutoDelete(true);

    connect(this, SIGNAL(sig_httptaskreturn(SDK_USER_INFO_T, int, void*, bool)),&LibCurlSdkHttp::getInstance(),
            SIGNAL(sig_HttpJobReturn(SDK_USER_INFO_T, int, void*, bool)) );
}

SDKTask::~SDKTask()
{
}

void SDKTask::run()
{
    int ret = 0;
    switch(m_nCmd)
    {
        case API_TYPE_SET_BRIGHTNESS:
            ret = HttpSdk::getInstance().setBrightness(m_stUser, m_pParam);
        break;
        case API_TYPE_GET_BRIGHTNESS:
            ret = HttpSdk::getInstance().getBrightness(m_stUser, m_pParam);
        break;
        case API_TYPE_SET_IMAGEPARAMS:
            ret = HttpSdk::getInstance().setImageParams(m_stUser, m_pParam);
        break;
        case API_TYPE_GET_IMAGEPARAMS:
            ret = HttpSdk::getInstance().getImageParams(m_stUser, m_pParam);
        break;
        case API_TYPE_SET_TESTPARAM:
            ret = HttpSdk::getInstance().setTestParam(m_stUser, m_pParam);
        break;
        case API_TYPE_GET_TESTPARAM:
            ret = HttpSdk::getInstance().getTestParam(m_stUser, m_pParam);
        break;

    }

    if(m_nCmd >= API_TYPE_SET_BRIGHTNESS && m_nCmd <= API_TYPE_HTTP_MAX)
    {
        if(ret == 0)
            emit sig_httptaskreturn(m_stUser, m_nCmd, m_pParam, true);
        else
            emit sig_httptaskreturn(m_stUser, m_nCmd, m_pParam, false);
    }
}

curlsdk.h
#ifndef CURLSDK_H
#define CURLSDK_H
#include <QMutex>
#include "curl.h"
#include "commondef.h"

using namespace std;

class CurlSdk
{
public:
    CurlSdk();
    virtual ~CurlSdk();

    static CurlSdk& getInstance();

    //Http Get请求
    int HttpGet(const string& strUrl, string& strResponse);
    //Http Post请求
    int HttpPost(const string& strUrl, const string& strPost, const string& sHeader, string& strResponse);

    void SetDebug(bool bDebug);

private:
    bool m_bDebug;
    QMutex m_lock;

};

#endif // CURLSDK_H

curlsdk.cpp
#include "curlsdk.h"

CurlSdk::CurlSdk()
{
    m_bDebug = false;

    CURLcode res = curl_global_init(CURL_GLOBAL_ALL);
    if(CURLE_OK != res)
    {
        MY_DEBUG << "CurSdk curl_global_init Failed.";
    }
}

CurlSdk::~CurlSdk()
{
    curl_global_cleanup();
}

CurlSdk &CurlSdk::getInstance()
{
    static CurlSdk s_obj;
    return s_obj;
}

static size_t onWriteFunc(char *pData, size_t size, size_t nmemb, string* pWriteData)
{
    if(nullptr == pWriteData)
        return 0;

    size_t len = size * nmemb;
    pWriteData->append(pData, len);
    return len;
}

static int OnDebug(CURL *, curl_infotype itype, char * pData, size_t size, void *)
{
    Q_UNUSED(size);
    if(itype == CURLINFO_TEXT)
    {
        MY_DEBUG << "[TEXT]:" << pData;
    }
    else if(itype == CURLINFO_HEADER_IN)
    {
        MY_DEBUG << "[HEADER_IN]:" << pData;
    }
    else if(itype == CURLINFO_HEADER_OUT)
    {
        MY_DEBUG << "[HEADER_OUT]:" << pData;
    }
    else if(itype == CURLINFO_DATA_IN)
    {
        MY_DEBUG << "[DATA_IN]:" << pData;
    }
    else if(itype == CURLINFO_DATA_OUT)
    {
        MY_DEBUG << "[DATA_OUT]:" << pData;
    }
    return 0;
}

int CurlSdk::HttpGet(const string& strUrl, string& strResponse)
{
    CURLcode res;
    CURL* pCurl = curl_easy_init();
    if(nullptr == pCurl)
    {
        return CURLE_FAILED_INIT;
    }

    if(m_bDebug)
    {
        curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1);
        curl_easy_setopt(pCurl, CURLOPT_DEBUGFUNCTION, OnDebug);
    }

    curl_easy_setopt(pCurl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(pCurl, CURLOPT_READFUNCTION, NULL);
    curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, onWriteFunc);
    curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, static_cast<void*>(&strResponse));
    curl_easy_setopt(pCurl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);//开启digest认证

    //当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。
    //如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。
    curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1);

    curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 3);
    curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 3);

    res = curl_easy_perform(pCurl);
    curl_easy_cleanup(pCurl);

    return res;
}

int CurlSdk::HttpPost(const string& strUrl, const string& strPost, const string &sHeader, string& strResponse)
{
    QMutexLocker guard(&m_lock);

    CURLcode res;
    CURL* pCurl = curl_easy_init();
    if(nullptr == pCurl)
    {
        return CURLE_FAILED_INIT;
    }

    if(m_bDebug)
    {
        curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1);
        curl_easy_setopt(pCurl, CURLOPT_DEBUGFUNCTION, OnDebug);
    }

    curl_easy_setopt(pCurl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(pCurl, CURLOPT_POST, 1);
    curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, strPost.c_str());
    curl_easy_setopt(pCurl, CURLOPT_READFUNCTION, NULL);
    curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, onWriteFunc);
    curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, static_cast<void*>(&strResponse));
    curl_easy_setopt(pCurl, CURLOPT_NOSIGNAL, 1);
    curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 8);
    curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 8);

    struct curl_slist *pSlist = nullptr;
    pSlist = curl_slist_append(pSlist, sHeader.c_str());
    curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pSlist);

    res = curl_easy_perform(pCurl);
    curl_easy_cleanup(pCurl);

    return res;
}

void CurlSdk::SetDebug(bool bDebug)
{
    m_bDebug = bDebug;
}

3.2 生成的库:

在这里插入图片描述

4. sdk库调用demo

4.1 在pro文件中增加库链接和头文件包含:

4.2 拷贝库和头文件到demo工程上

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.3 demo代码 (客户端使用libcurl)

curlsdkdemo.h
#ifndef CURLSDKDEMO_H
#define CURLSDKDEMO_H

#include <QMainWindow>
#include "libcurlsdk.h"

namespace Ui {
class CurlSdkDemo;
}

class CurlSdkDemo : public QMainWindow
{
    Q_OBJECT

public:
    explicit CurlSdkDemo(QWidget *parent = nullptr);
    ~CurlSdkDemo();

private slots:
    void on_Btn_SetBrightness_clicked();

    void on_Btn_GetBrightness_clicked(); 
    
    void on_Btn_SendUrlByGet_clicked();

    void on_btn_post_set_clicked();

    void on_btn_post_get_clicked();

    void on_Btn_PostSendCustom_clicked();

    void on_Btn_SetLogLevel_clicked();

    void on_Btn_SetLogSave_clicked();

    void slot_getHttpJobReturn(SDK_USER_INFO_T stUser, int eCmd, void* IpcParam, bool bSucc);

    void on_Btn_SetAllImageConfig_clicked();

    void on_Btn_GetAllImageConfig_clicked();

private:
    Ui::CurlSdkDemo *ui;
};

#endif // CURLSDKDEMO_H


curlsdkdemo.cpp
#include "curlsdkdemo.h"
#include "ui_curlsdkdemo.h"
#include <QDebug>
#include <QCoreApplication>
#include <QtConcurrent>
#include "QFuture"
#include "QFutureWatcher"
#include <QMessageBox>


CurlSdkDemo::CurlSdkDemo(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CurlSdkDemo)
{
    //注册传递类型
    qRegisterMetaType<SDK_USER_INFO_T>("SDK_USER_INFO_T");

    connect(&LibCurlSdkHttp::getInstance(), SIGNAL(sig_HttpJobReturn(SDK_USER_INFO_T,int,void*,bool)),
            this, SLOT(slot_getHttpJobReturn(SDK_USER_INFO_T,int,void*,bool)));

    ui->setupUi(this);
}

CurlSdkDemo::~CurlSdkDemo()
{
    delete ui;
}
/**********************************
 * Log Operate
 * ********************************/
void CurlSdkDemo::on_Btn_SetLogLevel_clicked()
{
    LibCurlSdkHttp::getInstance().setLogLevel(LOG_LEVEL_INFO);
}

void CurlSdkDemo::on_Btn_SetLogSave_clicked()
{
    QString sPath = qApp->applicationDirPath() + "/Log";
    QDir dir(sPath);
    if(!dir.exists())
    {
        dir.mkdir(sPath);//只创建一级子目录,即必须保证上级目录存在
    }

    LibCurlSdkHttp::getInstance().setLogSave(true, sPath);
}

/**********************************
 * Http:
 * Brightness (Get)
 * ********************************/
void CurlSdkDemo::on_Btn_SetBrightness_clicked()
{
    SDK_USER_INFO_T sUser;
    snprintf(sUser.sIP, sizeof(sUser.sIP), "%s", "127.0.0.1");
    sUser.nPort = 8080;
    snprintf(sUser.sUserName, sizeof(sUser.sUserName), "%s", "admin");
    snprintf(sUser.sPassword, sizeof(sUser.sPassword), "%s", "admin");

    int nBrightness = ui->lineEdit_SetValByGet->text().toInt();

    LibCurlSdkHttp::getInstance().SdkAddJob(sUser, API_TYPE_SET_BRIGHTNESS, (void*)(&nBrightness));
}

int g_nBrightness = 0;
void CurlSdkDemo::on_Btn_GetBrightness_clicked()
{
    SDK_USER_INFO_T sUser;
    snprintf(sUser.sIP, sizeof(sUser.sIP), "%s", "127.0.0.1");
    sUser.nPort = 8080;
    //snprintf(sUser.sUserName, sizeof(sUser.sUserName), "%s", "admin");
    //snprintf(sUser.sPassword, sizeof(sUser.sPassword), "%s", "admin");

    LibCurlSdkHttp::getInstance().SdkAddJob(sUser, API_TYPE_GET_BRIGHTNESS, (void*)(&g_nBrightness));
}
/**********************************
 * Http:
 * All Image Config (Get)
 * ********************************/
IMAGE_SETTINGS_T g_stImageSet;
void CurlSdkDemo::on_Btn_SetAllImageConfig_clicked()
{
    SDK_USER_INFO_T sUser;
    snprintf(sUser.sIP, sizeof(sUser.sIP), "%s", "127.0.0.1");
    sUser.nPort = 8080;
    //snprintf(sUser.sUserName, sizeof(sUser.sUserName), "%s", "admin");
    //snprintf(sUser.sPassword, sizeof(sUser.sPassword), "%s", "admin");

    IMAGE_SETTINGS_T imageSet;
    imageSet.nBrightness = ui->lineEdit_Brightness->text().toInt();
    imageSet.nContrast = ui->lineEdit_Contrast->text().toInt();
    imageSet.nSaturation = ui->lineEdit_Saturation->text().toInt();
    imageSet.nSharpness = ui->lineEdit_Sharpness->text().toInt();
    imageSet.nFLevel = ui->lineEdit_FLevel->text().toInt();

    LibCurlSdkHttp::getInstance().SdkAddJob(sUser, API_TYPE_SET_IMAGEPARAMS, (void*)(&imageSet));
}

void CurlSdkDemo::on_Btn_GetAllImageConfig_clicked()
{
    SDK_USER_INFO_T sUser;
    snprintf(sUser.sIP, sizeof(sUser.sIP), "%s", "127.0.0.1");
    sUser.nPort = 8080;
    //snprintf(sUser.sUserName, sizeof(sUser.sUserName), "%s", "admin");
    //snprintf(sUser.sPassword, sizeof(sUser.sPassword), "%s", "admin");

    LibCurlSdkHttp::getInstance().SdkAddJob(sUser, API_TYPE_GET_IMAGEPARAMS, (void*)(&g_stImageSet));
}

/**********************************
 * Http:
 * Send Url (Get) no in thread
 * ********************************/
void CurlSdkDemo::on_Btn_SendUrlByGet_clicked()
{
    QString sUrl = ui->lineEdit_SetParamByGetUrl->text();
    QString sResponse;
    if(LibCurlSdkHttp::getInstance().SendHttpGet(sUrl, sResponse) == 0)
        ui->textEdit_RecvGet->setText(sResponse);
}

/**********************************
 * Http:
 * Send Url (Get) no in thread
 * ********************************/
int g_nTestParam = 0;
void CurlSdkDemo::on_btn_post_set_clicked()
{
    int nValue = ui->lineEdit_SetValByPost->text().toInt();

    SDK_USER_INFO_T sUser;
    snprintf(sUser.sIP, sizeof(sUser.sIP), "%s", "127.0.0.1");
    sUser.nPort = 8080;

    //snprintf(sUser.sUserName, sizeof(sUser.sUserName), "%s", "admin");
    //snprintf(sUser.sPassword, sizeof(sUser.sPassword), "%s", "admin");

    LibCurlSdkHttp::getInstance().SdkAddJob(sUser, API_TYPE_SET_TESTPARAM, (void*)(&nValue));
}

void CurlSdkDemo::on_btn_post_get_clicked()
{
    SDK_USER_INFO_T sUser;
    snprintf(sUser.sIP, sizeof(sUser.sIP), "%s", "127.0.0.1");
    sUser.nPort = 8080;
    //snprintf(sUser.sUserName, sizeof(sUser.sUserName), "%s", "admin");
    //snprintf(sUser.sPassword, sizeof(sUser.sPassword), "%s", "admin");

    LibCurlSdkHttp::getInstance().SdkAddJob(sUser, API_TYPE_GET_TESTPARAM, (void*)(&g_nTestParam));
}

void CurlSdkDemo::on_Btn_PostSendCustom_clicked()
{
    QString sUrl = ui->textEdit_PostUrl->toPlainText();
    QString sParam = ui->textEdit_PostParam->toPlainText();
    QString sHead = ui->textEdit_PostHead->toPlainText();
    QString sResponse;
    if(LibCurlSdkHttp::getInstance().SendHttpPost(sUrl, sParam, sHead, sResponse) == 0)
        ui->textEdit_RecvPost->setText(sResponse);
}

/**********************************
 * Http:
 * Return Content
 * ********************************/
void CurlSdkDemo::slot_getHttpJobReturn(SDK_USER_INFO_T stUser, int eCmd, void *IpcParam, bool bSucc)
{
    qDebug() << __FUNCTION__ << "sIP:" << stUser.sIP << ", nPort:" << stUser.nPort << ", sUserName:" << stUser.sUserName <<\
             "sPwd:" << stUser.sPassword;

    Q_UNUSED(IpcParam);

    QString sResult;
    if(bSucc)
        sResult = "Success!";
    else
        sResult = "Failed!";

    switch(eCmd)
    {
        case API_TYPE_SET_BRIGHTNESS:
            QMessageBox::information(this, "Title", sResult);
        break;
        case API_TYPE_GET_BRIGHTNESS:
            ui->lineEdit_ShowBrightness->setText(QString::number(g_nBrightness));
        break;
        case API_TYPE_SET_IMAGEPARAMS:
            QMessageBox::information(this, "Title", sResult);
        break;
        case API_TYPE_GET_IMAGEPARAMS:
            qDebug() << __FUNCTION__ << " Brightness:" << g_stImageSet.nBrightness<<\
                        " Contrast:" << g_stImageSet.nContrast << " Saturation:" << g_stImageSet.nSaturation<<\
                        " nSharpness:" << g_stImageSet.nSharpness << " FLevel:" << g_stImageSet.nFLevel;

            ui->lineEdit_GetBrightness->setText(QString::number(g_stImageSet.nBrightness));
            ui->lineEdit_GetSharpness->setText(QString::number(g_stImageSet.nSharpness));
            ui->lineEdit_GetContrast->setText(QString::number(g_stImageSet.nContrast));
            ui->lineEdit_GetSaturation->setText(QString::number(g_stImageSet.nSaturation));
            ui->lineEdit_GetFLevel->setText(QString::number(g_stImageSet.nFLevel));
        break;
        case API_TYPE_SET_TESTPARAM:
            QMessageBox::information(this, "Title", sResult);
        break;
        case API_TYPE_GET_TESTPARAM:
            ui->lineEdit_GetValByPost->setText(QString::number(g_nTestParam));
        break;

    }
}

4.4 demo 程序界面

在这里插入图片描述

5. http服务器 (服务器使用QTcpServer)

5.1 核心代码

5.1 myhttpserver.h
#ifndef MYHTTPSERVER_H
#define MYHTTPSERVER_H

#include <QMainWindow>

namespace Ui {
class myHttpServer;
}


QT_BEGIN_NAMESPACE
class QTcpServer;
class QTcpSocket;
QT_END_NAMESPACE

class myHttpServer : public QMainWindow
{
    Q_OBJECT

public:
    explicit myHttpServer(QWidget *parent = 0);
    ~myHttpServer();

    int SumNums(QVector<int> nums);

protected slots:
    void newConnectionSlot();
    void errorStringSlot();
    void sendMsg();

private:
    QTcpServer *m_tcpServer;
    QTcpSocket *m_tcpSocket;
    QString m_SocketInfo;

    int m_nBrightness;
    int m_nContrast;
    int m_nSaturation;
    int m_nSharpness;
    int m_nFLevel;
    int m_nTestVal;

private:
    Ui::myHttpServer *ui;
};

#endif // MYHTTPSERVER_H
5.2 myhttpserver.cpp
#include "myhttpserver.h"
#include "ui_myhttpserver.h"
#include <QTcpServer>
#include <QDebug>
#include <QTcpSocket>
#include <QJsonObject>
#include <QJsonDocument>
#include "QAbstractSocket"
#include "QStringList"

myHttpServer::myHttpServer(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::myHttpServer)
{
    ui->setupUi(this);
    m_tcpServer = new QTcpServer(this);
    m_tcpServer->listen(QHostAddress::Any, 8080);
    connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(newConnectionSlot()));
    connect(m_tcpServer, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(errorStringSlot()));
}

myHttpServer::~myHttpServer()
{
    m_tcpServer->close();
    delete ui;
}

int myHttpServer::SumNums(QVector<int> nums)
{
    int res = 0;
    foreach(int num, nums) {
        res += num;
    };
    return res;
}
void myHttpServer::newConnectionSlot()
{
    ui->textEdit->append("newConnectionSlot() called!");
    m_tcpSocket = m_tcpServer->nextPendingConnection();
    connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(sendMsg()));
}
void myHttpServer::errorStringSlot()
{
    ui->textEdit->append(m_tcpServer->errorString());
}

void myHttpServer::sendMsg()
{
    QByteArray data = m_tcpSocket->readAll();
    QString m_requestInfo = data;
    m_SocketInfo += m_requestInfo;
    if (m_requestInfo.indexOf("=")>0)
    {
        ui->textEdit->append(m_SocketInfo);
        //qDebug() << m_requestInfo;

        QStringList list = m_SocketInfo.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
        qDebug() << list;
        if (!list.empty())
        {
            QStringList headlist = QString(list[0]).split(QRegExp("[ ]"));
            QString m_requestMethod = headlist[0];

            qDebug() << "headlist[1]:" << headlist[1];

            if (m_requestMethod == "GET" && headlist[1].contains("my.rq"))
            {
                QStringList ParamList = headlist[1].split('&');
                QVector<int> nums;
                QString contentStr = "";

                foreach(QString str, ParamList) {

                    if(str.contains("setbrightnessval"))
                    {
                        m_nBrightness = str.split('=')[1].toInt();
                        qDebug() << "m_nBrightness:" << m_nBrightness;
                        contentStr = "OK ";
                    }
                    else if(str.contains("setcontrastval"))
                    {
                        m_nContrast = str.split('=')[1].toInt();
                        contentStr = "OK ";
                    }
                    else if(str.contains("setsaturationval"))
                    {
                        m_nSaturation = str.split('=')[1].toInt();
                        contentStr = "OK ";
                    }
                    else if(str.contains("setsharpnessval"))
                    {
                        m_nSharpness = str.split('=')[1].toInt();
                        contentStr = "OK ";
                    }
                    else if(str.contains("setnflevelval"))
                    {
                        m_nFLevel = str.split('=')[1].toInt();
                        contentStr = "OK ";
                    }
                    else if(str.contains("getparam=brightnessval"))
                    {
                        contentStr += QString("OK brightnessval=%1").arg(m_nBrightness);
                    }
                    else if(str.contains("getparam=contrastval"))
                    {
                        contentStr += QString("OK contrastval=%1").arg(m_nContrast);
                    }
                    else if(str.contains("getparam=saturationval"))
                    {
                        contentStr += QString("OK saturationval=%1").arg(m_nSaturation);
                    }
                    else if(str.contains("getparam=sharpnessval"))
                    {
                        contentStr += QString("OK sharpnessval=%1").arg(m_nSharpness);
                    }
                    else if(str.contains("getparam=nflevelval"))
                    {
                        contentStr += QString("OK nflevelval=%1").arg(m_nFLevel);
                    }
                };

                //send msg
                QString str = "HTTP/1.1 200 OK\r\n";
                str.append("Server:nginx\r\n");
                str.append("Content-Type:text/html;charset=UTF-8\r\n");
                str.append("Connection:keep-alive\r\n");
                str.append(QString("Content-Length:%1\r\n\r\n").arg(contentStr.size()));
                if(!contentStr.isEmpty())
                    str.append(contentStr);
                else
                {
                    str.append(contentStr);
                }

                m_tcpSocket->write(str.toStdString().c_str());
            }

            if (m_requestMethod == "POST")
            {
                QString params;
                if (QString(list[5]).size()>1)
                {
                    params = list[5];

                }

                qDebug() << "params:" << params;
                if (params.contains("setparam"))
                {
                    QStringList valueList = params.split('=');
                    m_nTestVal = valueList[1].toInt();

                    QJsonObject res;
                    res.insert("param", QJsonValue(m_nTestVal));
                    QJsonDocument documentJson(res);
                    QString strJson(documentJson.toJson(QJsonDocument::Compact));

                    QByteArray dataArray = documentJson.toJson();

                    //send msg
                    QString str = "HTTP/1.1 200 OK\r\n";
                    str.append("Server:nginx\r\n");
                    str.append("Content-Type:application/json;charset=UTF-8\r\n");
                    str.append("Connection:keep-alive\r\n");
                    str.append(QString("Content-Length:%1\r\n\r\n").arg(strJson.size()));
                    str.append(strJson);
                    m_tcpSocket->write(str.toStdString().c_str());
                }
                else if(params.contains("getparam"))
                {
                    QJsonObject res;
                    res.insert("param", QJsonValue(m_nTestVal));
                    QJsonDocument documentJson(res);
                    QString strJson(documentJson.toJson(QJsonDocument::Compact));

                    QByteArray dataArray = documentJson.toJson();

                    //send msg
                    QString str = "HTTP/1.1 200 OK\r\n";
                    str.append("Server:nginx\r\n");
                    str.append("Content-Type:application/json;charset=UTF-8\r\n");
                    str.append("Connection:keep-alive\r\n");
                    str.append(QString("Content-Length:%1\r\n\r\n").arg(strJson.size()));
                    str.append(strJson);
                    m_tcpSocket->write(str.toStdString().c_str());
                }
            }
        }
        m_SocketInfo = "";
    }
}

5.2 服务器界面

在这里插入图片描述

6. 完整工程代码链接

https://download.csdn.net/download/linyibin_123/86952628

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你可以使用libcurlQt中发送HTTP请求,与Flask服务器进行通信。以下是一个简单的示例代码: ```c++ #include <QCoreApplication> #include <QDebug> #include <QUrl> #include <curl/curl.h> // 回调函数,用于处理curl请求的响应数据 size_t handle_response(char *buffer, size_t size, size_t nmemb, void *userdata) { QByteArray *response = static_cast<QByteArray*>(userdata); response->append(buffer, size * nmemb); return size * nmemb; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 初始化curl curl_global_init(CURL_GLOBAL_ALL); CURL *curl = curl_easy_init(); // 设置请求的URL QUrl url("http://localhost:5000/api/test"); // 设置curl选项 curl_easy_setopt(curl, CURLOPT_URL, url.toString().toStdString().c_str()); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle_response); // 发送请求 QByteArray response; curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); CURLcode result = curl_easy_perform(curl); if (result != CURLE_OK) { qDebug() << "Error: " << curl_easy_strerror(result); } else { qDebug() << "Response: " << response; } // 清理curl curl_easy_cleanup(curl); curl_global_cleanup(); return a.exec(); } ``` 在上面的示例中,我们使用了`curl_easy_setopt`函数设置了curl选项,包括请求的URL、是否跟随重定向、响应数据的处理函数等。我们使用了`curl_easy_perform`函数发送请求并获取响应数据,最后使用`curl_easy_cleanup`函数清理curl。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅笑一斤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值