libCurl实现HTTP请求

libCurl是一个多协议、跨平台的客户端URL传输库;使用libCurl可方便地进行HTTP请求。

接口说明

libCurl提供easy interfacemulti interface两种HTTP请求方式;本文主要是easy interface的使用说明。

使用步骤

libCurl主要采用Callback方式完成数据传输,设置好参数后和回调函数后,在满足条件时会自动调用相应的回调函数实现对应功能。一般按如下顺序调用:

  • CURLcode curl_global_init(long flags):初始化库(只能调用一次),若在调用curl_easy_init时还未调用此函数,则libCurl库会自动调用此初始化函数。
  • CURL *curl_easy_init():初始化一个CURL指针(easy_handle对象,用于一系列easy函数中)。
  • CURLcode curl_easy_setopt(CURL *handle, CURLoption option, parameter):设置传输选项(参数及回调函数);一般会多次调用。
  • CURLcode curl_easy_perform(CURL *handle):完成传输任务。
  • void curl_easy_cleanup(CURL *handle):清理释放
  • void curl_global_cleanup(void):清理库,在使用结束时调用。

setopt函数部分选项说明

curl所有设置都是在curl_easy_setopt中完成,其选项众多;部分常见选项:

  • CURLOPT_URL:设定请求的URL;
  • CURLOPT_HTTPHEADER:设定请求的HTTP头数据;
  • CURLOPT_POSTFIELDS,CURLOPT_POSTFIELDSIZE:POST请求时,设定发送的数据和长度。
  • CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA:设定如何处理接收到的数据,WRITEFUNCTION设定回调函数size_t callback(void *ptr, size_t size, size_t nmemb, void *stream),其中stream参数即为通过WRITEDATA设定的参数。
  • CURLOPT_HEADERFUNCTION,CURLOPT_HEADERDATA:设定如何处理接收到的HTTP头数据;
  • CURLOPT_VERBOSE:设定输出信息,当第三个参数为1时,会输出详细的操作信息(方便调试);
  • CURLOPT_TIMEOUT,CURLOPT_CONNECTIONTIMEOU:设定传输与请求的超时时间,单位为秒;
  • CURLOPT_FOLLOWLOCATION,CURLOPT_MAXREDIRS:设定是否允许重定向(FOLLOWLOCATION非零时,会自动处理302错误),及最大重定向次数;

示例

以下是get与post请求的示例程序。

写数据回调

在有数据接收到时会被调用,size*nmemb是接收到的数据长度,userp是用户传递的接收数据的指针(示例中为string指针)。

static size_t http_curl_write_data(void *buffer, size_t size, size_t nmemb, void *userp) {
    if(NULL==userp || NULL==buffer || 0 == size)
        return 0;

    size_t realSize = size*nmemb;
    std::string *pstr = (std::string*)userp;
    if(NULL != pstr){
        pstr->append((const char*)buffer, realSize);
    }

    return realSize;
}

GET请求

请求的头信息通过map传入,返回接收到的response。

  • 请求头通过curl_slist_append组成一个链表后,作为参数传入;
  • CURLOPT_POST设为零;表示为GET请求;
  • 在perform请求成功后,还需通过curl_easy_getinfo获取对应的返回code,以判断请求是否真正成功。
string getRequest(const string &strUrl, const std::map<string, string> &mapHeader) {
    CURL *curl = curl_easy_init();
    if(NULL == curl){
        // ERROR:
        return "ERROR: call curl_easy_init fail";
    }

    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());

    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charsets: utf-8");
    for(auto &h:mapHeader){
        headers = curl_slist_append(headers, buildHeader(h).c_str());
    }
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    curl_easy_setopt(curl, CURLOPT_POST, 0); // GET request

    string strResp;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&strResp);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_curl_write_data);

    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
    CURLcode res = curl_easy_perform(curl);
    bool bRet = false;
    if(res != CURLE_OK){ // connect fail
        // ERROR
        strResp = "ERROR: Connect fail: " + res;
    }
    else{
        long respCode;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &respCode);
        if(respCode == 200) {
            bRet = true; // success
        }
        else{
            // error-info in strResp
        }
    }

    curl_easy_cleanup(curl);
    curl_slist_free_all(headers);

    return strResp;
}

POST请求

发送的数据以JSON字符串参数的形式传入:

  • 默认即为POST请求,不需要做特殊设定;
  • 通过POSTFIELDS与POSTFIELDSIZE设定要发送的JSON数据;
string postRequest(string strUrl, string strJson) {
    CURL *curl = curl_easy_init();
    if(NULL == curl){
        // ERROR:
        return "ERROR: call curl_easy_init fail";
    }

    curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());

    struct curl_slist *headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers, "charsets: utf-8");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strJson.c_str());
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strJson.length());

    string strResp;
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&strResp);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_curl_write_data);

    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
    CURLcode res = curl_easy_perform(curl);
    bool bRet = false;
    if(res != CURLE_OK){ // connect fail
        // ERROR
        strResp = "ERROR: Connect fail";
    }
    else{
        long respCode;
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &respCode);
        if(respCode == 200) {
            bRet = true; // success
        }
        else{
            // error-info in strResp
        }
    }

    curl_easy_cleanup(curl);
    curl_slist_free_all(headers);
    return strResp;
}
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值