libcurl实现http及https方式下载和访问

准备条件:

编译好的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;
}
————————————————
版权声明:本文为CSDN博主「半雨微凉丶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/myruo/article/details/80591372

猜你喜欢

转载自blog.csdn.net/qq_21743659/article/details/126948976