由于项目需求需要发送http_post去请求数据,所以上网去寻找了一些发送http请求的方法,发现libcurl较为常用,然后根据官网上的例子,对libcurl做了一些简单的封装,支持多线程,并且有进度条显示,希望对大家有帮助,如有发现问题,欢迎批评指正~
代码(libcurl_http.h)如下:
#pragma once
#include "curl/curl.h"
#include <time.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <string>
using namespace std;
#define error(args) do{ \
printf("[%s] - %s:%s:%d-----%s, %s\n" , "error", __FILE__, __FUNCTION__, __LINE__, strerror(errno), args); \
} while(0)
namespace INTERNET_SERVICE {
class curl_http_send
{
public:
curl_http_send();
~curl_http_send();
static size_t receive_data(void * contents, size_t size, size_t nmemb, void *pcurl);
static int progress_callback(void * clientp,double dltotal,double dlnow,double ultotal,double ulnow);
static size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata);
string HttpGet(const std::string & strUrl, const long nTimeout=10);
string HttpPost(const std::string & strUrl, const char * send_data, const long nTimeout=10);
private:
curl_http_send(curl_http_send &&);
curl_http_send(const curl_http_send &);
curl_http_send &operator=(curl_http_send &&);
curl_http_send &operator=(const curl_http_send &);
private:
volatile double buf_size;
string data;
};
}
代码(libcurl_http.cpp)如下:
#include "curl_http_post.h"
#include <stdlib.h>
#include <string.h>
namespace INTERNET_SERVICE {
curl_http_send::curl_http_send():buf_size(0){
}
curl_http_send::~curl_http_send()
{
}
size_t curl_http_send::receive_data(void * contents, size_t size, size_t nmemb, void *pcurl)
{
FILE *f_p;
curl_http_send *curl_p = (curl_http_send *)pcurl;
f_p = fopen("data.txt", "a+");
if (!f_p) {
error("data.txt open failure\n");
}
fwrite(contents, size*nmemb, 1, f_p);
fclose(f_p);
curl_p->data.append((char*)contents, size * nmemb);
return size * nmemb;
}
int curl_http_send::progress_callback(void * clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
curl_http_send *curl_p = (curl_http_send *)clientp;
if(curl_p->buf_size)
printf("\r[%u%%]", (unsigned int)((dlnow / curl_p->buf_size) * (double)100));
return 0;
}
size_t curl_http_send::header_callback(char *buffer, size_t size, size_t nitems, void *userdata) {
curl_http_send *curl_p = (curl_http_send *)userdata;
char *buf = NULL;
char *buf_right = NULL;
buf = strtok_s(buffer, ":", &buf_right);
if (!strncmp("data-length", buf, sizeof("data-length"))) {
curl_p->buf_size = strtod(buf_right, NULL);
}
return size * nitems;
}
string curl_http_send::HttpGet(const std::string & strUrl, const long nTimeout)
{
data.clear();
CURLcode res;
CURL* pCURL = curl_easy_init();
if (!pCURL) {
error("curl_easy_init error");
curl_easy_cleanup(pCURL);
return "";
}
curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(pCURL, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, nTimeout);
curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, curl_http_send::receive_data);
curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, this);
curl_easy_setopt(pCURL, CURLOPT_PROGRESSFUNCTION, curl_http_send::progress_callback);
curl_easy_setopt(pCURL, CURLOPT_PROGRESSDATA, this);
curl_easy_setopt(pCURL, CURLOPT_HEADERFUNCTION, curl_http_send::header_callback);
curl_easy_setopt(pCURL, CURLOPT_HEADERDATA, this);
res = curl_easy_perform(pCURL);
if (res != CURLE_OK) {
error("curl_easy_perform error");
data.clear();
}
else {
long response_code;
curl_easy_getinfo(pCURL, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code == 200) {
printf("Data status normal\n");
}
else {
printf("Data status abnormal\n");
}
}
curl_easy_cleanup(pCURL);
return data;
}
string curl_http_send::HttpPost(const std::string & strUrl, const char * send_data, const long nTimeout)
{
data.clear();
CURLcode res;
CURL* pCURL = curl_easy_init();
struct curl_slist* headers = NULL;
if (!pCURL) {
error("curl_easy_init error");
curl_easy_cleanup(pCURL);
return "";
}
this->buf_size = 0;
CURLcode ret;
ret = curl_easy_setopt(pCURL, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, 10);
ret = curl_easy_setopt(pCURL, CURLOPT_POST, 1L);
headers = curl_slist_append(headers, "content-type:application/json");
if (headers == NULL) {
curl_slist_free_all(headers);
error("curl_slist_append error");
return "";
}
ret = curl_easy_setopt(pCURL, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(pCURL, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt(pCURL, CURLOPT_NOPROGRESS, 0L);
ret = curl_easy_setopt(pCURL, CURLOPT_POSTFIELDS, send_data);
ret = curl_easy_setopt(pCURL, CURLOPT_TIMEOUT, nTimeout);
ret = curl_easy_setopt(pCURL, CURLOPT_WRITEFUNCTION, curl_http_send::receive_data);
ret = curl_easy_setopt(pCURL, CURLOPT_WRITEDATA, this);
ret = curl_easy_setopt(pCURL, CURLOPT_PROGRESSFUNCTION, curl_http_send::progress_callback);
ret = curl_easy_setopt(pCURL, CURLOPT_PROGRESSDATA, this);
ret = curl_easy_setopt(pCURL, CURLOPT_HEADERFUNCTION, curl_http_send::header_callback);
ret = curl_easy_setopt(pCURL, CURLOPT_HEADERDATA, this);
res = curl_easy_perform(pCURL);
curl_slist_free_all(headers);
if (res != CURLE_OK) {
error("curl_easy_perform error");
data.clear();
}
else {
long response_code;
curl_easy_getinfo(pCURL, CURLINFO_RESPONSE_CODE, &response_code);
char *contentType = { 0 };
CURLcode return_code;
return_code = curl_easy_getinfo(pCURL, CURLINFO_CONTENT_TYPE, &contentType);
if ((CURLE_OK == return_code) && contentType)
cout << "请求的文件类型:" << contentType << endl;
if (response_code == 200) {
printf("Data status normal\n");
}
else {
printf("Data status abnormal\n");
}
}
curl_easy_cleanup(pCURL);
return data;
}
}
代码(main.cpp)如下:
#include "curl_http_post.h"
#include <fstream>
#include <windows.h>
#include <pthread.h>
#define URL "http://xxx"
#define OVER_TIME 500
static std::string GBKToUTF8(const char* strGBK)
{
int len = MultiByteToWideChar(CP_ACP, 0, strGBK, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len + 1];
memset(wstr, 0, len + 1);
MultiByteToWideChar(CP_ACP, 0, strGBK, -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len + 1];
memset(str, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
std::string strTemp = str;
if (wstr) delete[] wstr;
if (str) delete[] str;
return strTemp;
}
void * thread_run_function(void *ptr) {
printf("thread_run_function\n");
INTERNET_SERVICE::curl_http_send *p = new INTERNET_SERVICE::curl_http_send();
string str2 = GBKToUTF8("{\"standardId\": \"1191537941206355970\",\"attachedInformation\": \"ncdisp\"}");
string data = p->HttpPost(URL, str2.c_str(), OVER_TIME);
char filename[20];
sprintf(filename, "%s%u%s", "data", *(int *)ptr, ".txt");
FILE *fp = fopen(filename, "w");
fwrite(data.c_str(), data.size(), 1, fp);
fclose(fp);
fp = NULL;
delete p;
return NULL;
}
int main() {
curl_global_init(CURL_GLOBAL_ALL);
INTERNET_SERVICE::curl_http_send *p = new INTERNET_SERVICE::curl_http_send();
pthread_t thread1, thread2,thread3, thread4;
unsigned int index1 = 1, index2 = 2, index3 = 3, index4 = 4;
pthread_create(&thread1, NULL, thread_run_function, &index1);
pthread_create(&thread2, NULL, thread_run_function, &index2);
pthread_create(&thread3, NULL, thread_run_function, &index3);
pthread_create(&thread4, NULL, thread_run_function, &index4);
cout << "return data-> " << p->HttpGet("www.baidu.com") << endl;
string str2 = GBKToUTF8("{\"standardId\": \"1191537941206355970\",\"attachedInformation\": \"ncdisp\"}");
cout << "return data-> " << p->HttpPost(URL, str1.c_str(), OVER_TIME) << endl;
void *aaa;
pthread_join(thread1,&aaa);
pthread_join(thread2,&aaa);
pthread_join(thread3,&aaa);
pthread_join(thread4,&aaa);
delete p;
curl_global_cleanup();
system("pause");
return 0;
}
参考:
1.https://curl.haxx.se/libcurl/c/
2.https://blog.csdn.net/FK2016/article/details/82226683
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)