curl起始于1998年,是一款免费且开源的使用URL进行数据传输的命令行工具和共享库,支持DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP等应用层协议,并且支持SSL认证和断点续传等特性,通过命令行或脚本传输数据,广泛应用于汽车、电视机、路由器、打印机、音频设备、移动电话、平板电脑、机顶盒、媒体播放器等设备,同时也是成千上万应用程序的互联网数据传输引擎。
curl的官网是http://curl.se,可在官网上下载最新的稳定版本,当前最新的版本是2022/8/31发布的 7.85.0,进入下载界面后点击“curl-7.85.0.zip”进行下载,如下图所示:
完成下载后,对文件夹进行解压,解压完成后,打开“winbuild” 文件夹,找到“README.md”文件,该文件中详细介绍了libcurl的编译过程,编者以该文件为指导进行编译,并对编译过程及使用进行了如下总结:
首先确保已安装VC++编译工具,且版本不低于Visual Studio 6,这里强烈推荐使用最新版本。VC++是Windows平台下SDK的一部分,因而如果你仅是编译libcurl,并不需要安装整个的Visual Studio。如果希望支持zlib、openssl、c-ares、ssh2,须单独下载相关文件,并将这些文件拷贝至“deps”文件夹中。
第一步:在启动菜单中打开“Visual Studio 2013”文件夹下的“Visual Studio Tools”文件夹,然后以管理员权限打开“VS2013 x64 本机工具命令提示”命令行提示工具,如下图所示:
第二步:进入命令行提示窗口后,转到“winbuild”文件夹下,然后调用`nmake /f Makefile.vc`,同时可设置编译选项,格式如:nmake /f Makefile.vc mode=dll <options>,options详情可参见“README.md”文件。编译示例如下:
完成编译后,可在“builds”文件夹下找到编译成果, 在“libcurl-vc12-x64-release-dll-ipv6-sspi-schannel”文件夹下可找到编译好的libcurl.lib和libcurl.dll,如下图所示:
第三步:完成前两步的编译后,可将libcurl库导入到自己的项目工程下,并调用相应的API。导入步骤如下所示;
~~~
- Configuration Properties > Debugging > Environment
PATH=F:\curl-7.85.0\builds\libcurl-vc10-x64-release-dll-ipv6-sspi-schannel\bin;%PATH%
- C/C++ > General > Additional Include Directories
F:\curl-7.85.0\builds\libcurl-vc10-x64-release-dll-ipv6-sspi-schannel\include;
- Linker > General > Additional Library Directories
F:\curl-7.85.0\builds\libcurl-vc10-x64-release-dll-ipv6-sspi-schannel\lib;
- Linker > Input > Additional Dependencies
libcurl.lib;
~~~
调用libcurl示例代码如下所示:
// LibcurlTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <curl\curl.h>
using namespace std;
#pragma region http定义
static string resp_data_str; //http通信返回的数据
#pragma endregion
#pragma region LIBCURL实现HTTP通信POST(可扩展)
//回调函数
size_t write_callback(char* ptr, size_t size, size_t nmemb, void* userdata)
{
size_t len = size * nmemb;
for (size_t i = 0; i < len; ++i)
{
resp_data_str += *ptr;
++ptr;
}
return len;
}
//实现HTTP通信
bool curl_http(string ip_port, string data)
{
char* send_data;
CURL* curl = NULL;
CURLcode res;
//待发送的数据
size_t num = data.size();//计算这个 UNICODE 实际由几个UTF-8字組成
send_data = (char*)malloc(data.size() + 1); //申请空间
if (send_data == NULL) //是否申请
{
return false;
}
memset(send_data, 0, data.size()); //初始化
memcpy(send_data, data.c_str(), data.size() + 1);
ofstream fout("SendData.txt");
fout << send_data;
fout.close();
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl)
{
curl_slist* http_headers = NULL;
http_headers = curl_slist_append(http_headers, "Accept: application/json");
http_headers = curl_slist_append(http_headers, "Content-Type: application/json");
http_headers = curl_slist_append(http_headers, "Accept-Charset:UTF8");
http_headers = curl_slist_append(http_headers, "Accept-Language: zh-cn;q=0.8,en;q=0.6,ja;q=0.4");
http_headers = curl_slist_append(http_headers, "User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, ip_port.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_headers);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, send_data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(send_data));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
return false;
}
curl_slist_free_all(http_headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return true;
}
else
{
return false;
}
}
#pragma endregion
int _tmain(int argc, _TCHAR* argv[])
{
curl_http("https://support.yjk.cn/api/admin/client_notice/online_upgrade_product_list","");
cout << "Response Data:" << endl;
cout << resp_data_str.c_str() << endl;
_tsystem("pause");
return 0;
}