【Qt】linux下Qt使用libcurl进行post请求
项目中使用qt的QNetworkAccessManager进行post请求,请求完成后过一会就崩溃了,没找到是什么原因。只能另想他法了,就想着使用其他库来实现,就用起了大名鼎鼎的libcurl。下面介绍linux下qt使用libcurl。首先安装libcurlgithub下载curl的源码,地址为:https://github.com/curl/curl,选择clone下载解压后进入目录,按顺序执
项目中使用qt的QNetworkAccessManager进行post请求,请求完成后过一会就崩溃了,没找到是什么原因。只能另想他法了,就想着使用其他库来实现,就用起了大名鼎鼎的libcurl。
下面介绍linux下qt使用libcurl。
首先安装libcurl
- github下载curl的源码,地址为:https://github.com/curl/curl,选择clone下载
- 解压后进入目录,按顺序执行
- ./buildconf (产生configure配置文件)
- ./configure
- make
- sudo make install
安装完成之后相关的头文件一般在/usr/local/include/curl,相关的东西都默认装在系统目录,qt是能够直接链接得到,就可以直接用了。
头文件直接包含#include "curl/curl.h"是能够直接识别的
在pro文件添加库
LIBS += -lcurl
直接添加,不用选择路径,默认在系统库查找
下面直接上代码
头文件:
#ifndef HTTPMANAGER_H
#define HTTPMANAGER_H
#include <QObject>
class HttpManager : public QObject
{
Q_OBJECT
public:
explicit HttpManager(QObject *parent = nullptr);
~HttpManager();
void setUrl(const QString &url);
void doPost(QByteArray data);
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
signals:
void sigFinished(const QByteArray &data);
void sigError(int code);
private:
QString m_url;
};
#endif // HTTPMANAGER_H
cpp文件:
#include "httpmanager.h"
#include "curl/curl.h"
#include <string>
#include <exception>
#include <QDebug>
HttpManager::HttpManager(QObject *parent):
QObject(parent)
{
// In windows, this will init the winsock stuff
curl_global_init(CURL_GLOBAL_ALL);
}
HttpManager::~HttpManager()
{
curl_global_cleanup();
}
void HttpManager::setUrl(const QString &url)
{
m_url = url;
}
void HttpManager::doPost(QByteArray data)
{
try
{
CURL *pCurl = NULL;
CURLcode res;
// get a curl handle
pCurl = curl_easy_init();
if (NULL != pCurl)
{
// 设置超时时间为5秒
curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 8);
// First set the URL that is about to receive our POST.
// This URL can just as well be a
// https:// URL if that is what should receive the data.
QByteArray url = m_url.toUtf8();
curl_easy_setopt(pCurl, CURLOPT_URL, url.constData());
//curl_easy_setopt(pCurl, CURLOPT_URL, "http://192.168.0.2/posttest.cgi");
std::vector<char> vec;
QByteArray resultData;
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &resultData);
// 设置http发送的内容类型为JSON
curl_slist *plist = curl_slist_append(NULL,
"Content-Type:application/json;charset=UTF-8");
curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, plist);
// 设置要POST的JSON数据
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, data.constData());
// Perform the request, res will get the return code
res = curl_easy_perform(pCurl);
// Check for errors
if (res != CURLE_OK)
{
emit sigError(res);
// printf("curl_easy_perform() failed:%s\n", curl_easy_strerror(res));
qDebug() << __FUNCTION__ << "song" << "error" << res;
}
qDebug() << __FUNCTION__ << "song22" << resultData;
emit sigFinished(resultData);
// always cleanup
curl_easy_cleanup(pCurl);
}
}
catch (std::exception &ex)
{
printf("curl exception %s.\n", ex.what());
}
}
size_t HttpManager::WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
QByteArray *replyData = (QByteArray *)userp;
char* pVal = (char*)contents;
for (size_t i = 0; i < size * nmemb; ++i)
{
replyData->push_back(pVal[i]);
}
return size * nmemb;
}
这是一个简单的post请求的实现,curl库对应函数的功能介绍可以另外百度。
这里主要说一下要注意的点:
1.如果请求返回超时错误,有可能是超时时间设短了,可以加长点
2.返回值的用法
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
这个地方有个回调函数,这个函数必须是静态函数,不能是类的成员函数,请求结束会进入到这里,其中contents是返回的内容,最后一个参数用于用户自定义的数据,意思就是这个回调返回的请求数据是一个临时数据,我们要把这个数据存下来或者自己拿来用,不然函数结束数据就没了,既然要存下来,那可以直接写文件,我这里使用的是存到一个ByteArray数据中,具体用法就是
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &resultData);
使用写数据的函数,这时候userp指向的就是resultData的地址,把返回的数据赋值给userp,就相当于给resultData赋值。对于习惯使用Qt相关用法的人来说,这个用法的确有点绕
在执行curl_easy_perform函数的时候会阻塞,请求完成后,会进入回调和写数据的过程,完成后数据就到了resultData,就结束啦。
下面看调用的代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "httpmanager.h"
#include <QJsonDocument>
#include <QJsonObject>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_pHttpManager = new HttpManager(this);
m_pHttpManager->setUrl("https://xxxx");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QJsonDocument json;
QJsonObject jsonObj;
jsonObj.insert("action", "xxx");
json.setObject(jsonObj);
m_pHttpManager->doPost(json.toJson());
}
整个用法就是这样,只用于post请求,还是挺简单的
更多推荐
所有评论(0)