libcurl使用样例

libcurl被很多软件厂商使用,libcurl提供了使用C或C++语言支持http访问,所有常用于客户端软件

本例学习了libcurl的写法,上代码:

#pragma once

#ifndef __RESTCLIENTPOOL_H__
#define __RESTCLIENTPOOL_H__
#include "./libcurl-vc16-x86-release-dll-ipv6-sspi-schannel/include/curl/curl.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <string>
#include <vector>
#include <queue>
using namespace std;

typedef size_t(*callback_func)(void* ptr, size_t size, size_t nmemb, void* stream);

struct curl_data
{
    string* response;
    callback_func cb;

    curl_data(const char* pUrl, callback_func func)
    {
        response = new std::string(pUrl);
        cb = func;
    }
    ~curl_data()
    {
        delete response;
    }
};

class RestClientPool
{
public:
    RestClientPool(void);
    ~RestClientPool(void);

public:

    /**
    * @brief HTTP GET请求
    * @param strUrl 输入参数,请求的Url地址,如:http://www.baidu.com
    * @param strResponse 输出参数,返回的内容
    * @return 返回是否Post成功
    */
    int Get(callback_func cb, std::string * strResponse);


public:
    void SetDebug(bool bDebug);
     int GlobleInit();//全局初始化,主程序调用一次
    void GlobleFint();

    CURL* GetCurl();
    CURL* CreateCurl();
    void PutCurl(CURL* curl);
private:
    bool m_bDebug;

    queue<CURL* > m_VectCurl;
    vector< curl_slist*> m_VectSlist;
    HANDLE hMutex;
};

#endif

// curl_multi_test.cpp : 定义控制台应用程序的入口点。
//

#include "RestClientPool.h"

// 唯一的应用程序

#       pragma comment(lib,  "libcurl-vc16-x86-release-dll-ipv6-sspi-schannel/lib/libcurl.lib")


RestClientPool::RestClientPool(void) :
    m_bDebug(false)
{
    GlobleInit();//全局初始化,主程序调用一次

    hMutex = CreateMutex(NULL, FALSE, NULL);
}

RestClientPool::~RestClientPool(void)
{
    for (curl_slist* p : m_VectSlist) {
        if (p != nullptr)
            curl_slist_free_all(p);
    }
    m_VectSlist.clear();

    if (m_VectCurl.size() > 0)
    {
        CURL* curl = m_VectCurl.front();
        m_VectCurl.pop();
        while (curl != nullptr) {
            curl_easy_cleanup(curl);
            if (m_VectCurl.size() <= 0)
                break;
            curl = m_VectCurl.front();
            m_VectCurl.pop();
        }
    }
    CloseHandle(hMutex);

    GlobleFint();
}

static int OnDebug(CURL*, curl_infotype itype, char* pData, size_t size, void*)
{
    if (itype == CURLINFO_TEXT)
    {
        //printf("[TEXT]%s\n", pData);
    }
    else if (itype == CURLINFO_HEADER_IN)
    {
        printf("[HEADER_IN]%s\n", pData);
    }
    else if (itype == CURLINFO_HEADER_OUT)
    {
        printf("[HEADER_OUT]%s\n", pData);
    }
    else if (itype == CURLINFO_DATA_IN)
    {
        printf("[DATA_IN]%s\n", pData);
    }
    else if (itype == CURLINFO_DATA_OUT)
    {
        printf("[DATA_OUT]%s\n", pData);
    }
    return 0;
}


CURL* RestClientPool::GetCurl()
{
    CURL* curl = NULL;
    WaitForSingleObject(hMutex, INFINITE);
    if (m_VectCurl.size() > 0)
    {

        curl = m_VectCurl.front();
        m_VectCurl.pop();

    }
    ReleaseMutex(hMutex);
    if (curl == NULL)
    {
        curl = CreateCurl();
    }
    return curl;
}

void RestClientPool::PutCurl(CURL* curl)
{
    WaitForSingleObject(hMutex, INFINITE);

    m_VectCurl.push(curl);
    ReleaseMutex(hMutex);
}


CURL* RestClientPool::CreateCurl()
{
    CURL* curl = curl_easy_init();
    if (NULL == curl)
    {
        return NULL;
    }


    curl_slist* list = nullptr;
    list = curl_slist_append(list, "Accept: text/json");
    //list = curl_slist_append(list, "Accept-Encoding: gzip");
    list = curl_slist_append(list, "Accept-Language: zh-CN,zh;q=0.9");
    list = curl_slist_append(list, "Content-Type: text/json");
    list = curl_slist_append(list, "Host: localhost:80");
    list = curl_slist_append(list, "Connection: Keep-Alive");
    //list = curl_slist_append(list, "Cookie: em_hq_fls=js; qgqp_b_id=7473a399162f1995601a1fb59c4bd05f; ct=2ix0h5AQ4v538wkocKxPcY_ilboT2srS08hrjybizJ5Kc58v02kimh6AZe2Yz7Z4p_1KLU7-LIqeBaC2WyrERVzjx1K9g8RgMIs1vO-lBw9ao0KHJ_bvxJhQkdtJspPVs3fqpWLR-rGfdSEiB6055Aqg2ux3Ej_WVoLrW9EXhrU");
    list = curl_slist_append(list, "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36");

    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
    if (m_bDebug)
    {
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug);
    }
    //curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);

    /* enable TCP keep-alive for this transfer */
    curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
    /* keep-alive idle time to 120 seconds */
    curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 300L);
    /* interval time between keep-alive probes: 60 seconds */
    curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, 20L);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
    /**
    * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。
    * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。
    */
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20);

    m_VectSlist.push_back(list);

    return curl;
}
void RestClientPool::SetDebug(bool bDebug)
{
    m_bDebug = bDebug;
}

int RestClientPool::GlobleInit()//全局初始化,主程序调用一次
{
    return curl_global_init(CURL_GLOBAL_ALL);
}
void RestClientPool::GlobleFint()
{
    curl_global_cleanup();
}


int RestClientPool::Get(callback_func func, std::string* strResponse)
{
    int res;
    //CURL* curl = CurlMutiTreadMutex::GetInstance()->muti_curl_easy_init();
    CURL* curl = GetCurl();
    if (NULL == curl)
    {
        return CURLE_FAILED_INIT;
    }

    curl_easy_setopt(curl, CURLOPT_URL, strResponse->c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, func);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)strResponse);
    res = curl_easy_perform(curl);
    if (res != 0)
    {
        printf("curl_easy_perform error %d\n", res);
    }
    PutCurl(curl);
    return res;
}


bool ctrlhandler(DWORD fdwctrltype)
{
    bool bRet = false;
    switch (fdwctrltype)
    {
        // handle the ctrl-c signal.
    case CTRL_C_EVENT:
        printf("ctrl-c event\n\n");
        bRet = true;
        break;
        // ctrl-close: confirm that the user wants to exit.
    case CTRL_CLOSE_EVENT:
        printf("ctrl-close event\n\n");
        bRet = true;
        break;
        // pass other signals to the next handler.
    case CTRL_BREAK_EVENT:
        printf("ctrl-break event\n\n");
        bRet = false;
        break;
    case CTRL_LOGOFF_EVENT:
        printf("ctrl-logoff event\n\n");
        bRet = false;
        break;
    case CTRL_SHUTDOWN_EVENT:
        printf("ctrl-shutdown event\n\n");
        bRet = false;
        break;
    default:
        break;;
    }

    return bRet;
}


 还有多线程并发的例子,欢迎到我的资源下载学习,彻底掌握libcurl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值