【第三方库】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;
}

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值