准备条件:
编译好的libcurl库,如果要支持https,需要和openssl一起编译,网上教程较多
示例代码:(使用loadlibrary的方式只是为了测试方便)
// libcurtest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#include "curl.h"
using namespace std;
size_t my_write_func( void *ptr, size_t size, size_t nmemb, FILE *stream )
{
if( stream != NULL )
return fwrite( ptr, size, nmemb, stream );
else
return 0;
}
//by zhaocl
int main()
{
HMODULE hdll = LoadLibrary( L"libcurl.dll" );
if( !hdll )
{
return -1;
}
typedef CURL * ( *PCURL_EASY_INIT )();
typedef CURLcode( *PCURL_EASY_SETOPT )( CURL*, CURLoption, ... );
typedef CURLcode( *PCURL_EASY_PERFORM )( CURL* );
typedef void( *PCURL_EASY_CLEANUP )( CURL * );
PCURL_EASY_SETOPT pFunction = NULL;
PCURL_EASY_PERFORM pFunction2 = NULL;
PCURL_EASY_INIT pFunction3 = NULL;
PCURL_EASY_CLEANUP pFunction4 = NULL;
pFunction3 = ( PCURL_EASY_INIT )GetProcAddress( hdll, "curl_easy_init" );
pFunction = ( PCURL_EASY_SETOPT )GetProcAddress( hdll, "curl_easy_setopt" );
pFunction2 = ( PCURL_EASY_PERFORM )GetProcAddress( hdll, "curl_easy_perform" );
pFunction4 = ( PCURL_EASY_CLEANUP )GetProcAddress( hdll, "curl_easy_cleanup" );
PCURL_EASY_INIT url_ini = ( PCURL_EASY_INIT )( PCURL_EASY_INIT )GetProcAddress( hdll, "curl_easy_init" );
if( !url_ini )
{
return -1;
}
CURL *curl;
CURLcode res;
//const char* strUrl = "Https://www.baidu.com";
const char* strUrl = "https://slproweb.com/download/Win64OpenSSL-1_0_2o.exe";
curl = url_ini(); //初始化
if( curl && strUrl )
{
//下载
FILE *outfile;
fopen_s( &outfile, "AxTools.exe", "wb" );
pFunction( curl, CURLOPT_URL, strUrl );
pFunction( curl, CURLOPT_WRITEDATA, outfile );
pFunction( curl, CURLOPT_SSL_VERIFYPEER, false ); //设定为不验证证书和HOST
pFunction( curl, CURLOPT_SSL_VERIFYHOST, false );
pFunction( curl, CURLOPT_WRITEFUNCTION, my_write_func );
pFunction( curl, CURLOPT_NOPROGRESS, FALSE );
pFunction( curl, CURLOPT_PROGRESSFUNCTION, NULL );
pFunction( curl, CURLOPT_PROGRESSDATA, NULL );
res = pFunction2( curl );
fclose( outfile );
/* always cleanup */
pFunction4( curl );
//访问
pFunction( curl, CURLOPT_URL, strUrl ); //设置url地址
pFunction( curl, CURLOPT_WRITEFUNCTION, my_write_func ); //设置回调函数
FILE *fp;
_wfopen_s( &fp, L"c:\\test.txt", _T( "wb+" ) );
pFunction( curl, CURLOPT_WRITEDATA, fp ); //设置写数据
pFunction( curl, CURLOPT_SSL_VERIFYPEER, false ); //设定为不验证证书和HOST
pFunction( curl, CURLOPT_SSL_VERIFYHOST, false );
res = pFunction2( curl ); //执行
if( res == CURLE_OK )
{
//ok 处理数据
pFunction4( curl );
return 1;
}
return -1;
}
return -1;
}
补充https示例:
实际项目中,还是用lib+头文件的方式居多
bool PostData(const char* pUrl, const char* pData, char** pOut, uint32_t* pBufLen)
{
try
{
CURL* pCurl = nullptr;
CURLcode res;
pCurl = curl_easy_init(); //curl_global_init不主动调用,会自动调用
if (nullptr != pCurl)
{
// 设置超时时间为8秒
curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 8);
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, pData);
curl_easy_setopt(pCurl, CURLOPT_URL, pUrl);
// 下面两个为验证对方和验证主机名,若为0,则跳过验证,我这个服务器必须验证才能得到请求数据
//curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L);
//curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 1L);
// 配置 https 请求所需证书
curl_easy_setopt(pCurl, CURLOPT_CAINFO, "/etc/msc/ca_info.pem");
curl_easy_setopt(pCurl, CURLOPT_SSLCERT, "/etc/msc/client.pem");
curl_easy_setopt(pCurl, CURLOPT_SSLKEY, "/etc/msc/client_key.pem");
curl_easy_setopt(pCurl, CURLOPT_KEYPASSWD, "your_key_password");
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, writer);
std::string strOut;
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, (void*)&strOut);
// Perform the request, res will get the return code
res = m_pCurl->easy_perform(pCurl);
uint32_t uSize = strOut.length() + 1;
*pOut = new char[uSize];
if (pOut)
{
memset(*pOut, 0x0, uSize);
memcpy(*pOut, strOut.c_str(), uSize);
*pBufLen = uSize;
cout<< L"recv data=" << strOut.c_str() << endl;
}
if (res != CURLE_OK)
{
cout<< L"curl_easy_perform() failed code=" << static_cast<uint32_t>(res) << endl;
}
curl_easy_cleanup(pCurl);
}
//curl_global_cleanup();
}
catch (std::exception& ex)
{
cout<< L"curl exception:" << ex.what() << endl;
}
return true;
}