项目中有时候需要在C++代码里借助HTTP请求获取一些在C++里较难实现转换的数据,比如IP->Hostname的转换(这里如果你有更好的方法在C++里调用系统api实现这个功能的请一定要告诉小编哥哥哦~),下面是个人的一点简单实践,主要有:libcurl源码编译安装、Get方法发起请求保存到变量然后输出。
编译安装libcurl:
从官网http://curl.haxx.se/download.html上下载最新版的curl-7.50.3.tar.gz,解压,编译,安装:
tar -zxvf curl-7.50.3.tar.gz
cd curl-7.50.3.tar.gz
./configure --prefix=/usr/local/curl
make && make install
其中prefix参数可以指定其它的安装目录,这里图方便就安装在/usr/loca/curl下了,
安装到非/usr下的目录时编译代码的时候就需要指定这个链接库的目录以及要链接的文件,
这里在测试过程种发现编译过了但提示有一个文件可能和系统的低版本的有冲突,./main: error while loading shared libraries: libcurl.so.4: cannot open shared object file: No such file or directory
个人猜测是系统版本的问题(在开发机上的测试结果...匿)
这里时间原因我也不去我外网的机器上测试了,原理是一样的只要链接上了curl库就可以在C++代码里使用啦~
实例代码
在这一步搜到的比较多的都是调用curl获取到返回后写入文件,在官网的文档里仔细查看发现了这个链接https://curl.haxx.se/libcurl/c/getinmemory.html,这样经过简单的改装我们就可以那来用了,我这里只实现了Get方式的HTTP请求,后面有需要Post方式的时候再来补充吧(好吧题主就是这么懒。。)
下面贴一下我的代码和测试结果:
测试结果(容易看出来这是一个从ip到hostname转换的一个接口):
源代码:GetCurl.h
POST请求、异步请求(后面有代码源文件)
void curl::post(string url,string data,string name) {
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
string postfiled = name + "=" + data;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfiled.c_str());
// curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "key=value");
/* Perform the request, res will get the return code */
//curl_easy_perform是阻塞调用
//res = curl_easy_perform(curl);
//if (res != CURLE_OK)
//fprintf(stderr, "curl_easy_perform() failed: %s\n",
//curl_easy_strerror(res));
//non-blocking fashion.非阻塞调用
CURLM * curl_m = curl_multi_init();
curl_multi_add_handle(curl_m, curl);
int running_handles;
curl_multi_perform(curl_m, &running_handles);
curl_multi_remove_handle(curl_m, curl);
/* always cleanup */
curl_easy_cleanup(curl);
curl_multi_cleanup(curl_m);
}
curl_global_cleanup();
return;
//上面是只提交key=>value的情景的,下面提供上传文件的代码
CURL *curl;
CURLcode res;
struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
struct curl_slist *headerlist=NULL;
static const char buf[] = "Expect:";
curl_global_init(CURL_GLOBAL_ALL);
/* Fill in the file upload field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "/path/to/sendfile.txt",
CURLFORM_END);
/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "submit",
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, name.c_str(),
CURLFORM_COPYCONTENTS, data.c_str(),
CURLFORM_END);
curl = curl_easy_init();
/* initialize custom header list (stating that Expect: 100-continue is not wanted /
headerlist = curl_slist_append(headerlist, buf);
if(curl) {
/ what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
/* then cleanup the formpost chain */
curl_formfree(formpost);
/* free slist */
curl_slist_free_all(headerlist);
}
return;
}