• 使用libcurl作为Http client


    产品通过HTTP协议为外部提供接口服务,常规情况是客户通过HTTP协议请求服务,服务结束后通过HTTP协议将服务记录POST到请求方。

    用原生C实现了一个简单的HTTP Client,只有简单的功能:

    1、实现HTTP GET/POST/PUT等方法;

    2、POST支持参数和数据POST;

    3、POST后接收返回值并关闭连接;

    4、支持连接TIMEOUT、同步接收返回值TIMEOUT;

    5、由于要设置超时,采用了多线程POST数据;

    在业务量大了后,会频繁调用HTTP Client,且本身是多线程POST数据,出现了内存异常,问题一直没有找到。因此考虑了第三方开源组件,比如libevent(HTTP Server采用libevent实现的)、libcurl,最终选择了libcurl。

    以下是结合网上例子修改的测试版本,测试后发现有内存泄漏问题,是由于自定义的http header指针未释放导致,并非网上所说curl_easy_perform导致。

    #include <stdio.h>
    #include <curl/curl.h>
    #define PROC_SUCCESS 0
    #define PROC_FAILED -1
    
    static long gCount = 0;
    
    int main()
    {
    time_t begin = time(NULL);
    curl_global_init(CURL_GLOBAL_DEFAULT);
    while(1)
    {
    const char *xml="<?xml />";
    CurlPost("http://10.0.0.1:8090/xdr",xml);
    gCount++;
    if(gCount%10000==0)
    {
    time_t now = time(NULL);
    fprintf(stdout,"CurlPost %ld usetime:%d
    ",gCount,now-begin);
    begin = now;
    }
    usleep(10000);
    }
    curl_global_cleanup();
    }
    
    int CurlPost(const char *uri,const char *xml)
    {
    int iRet = PROC_SUCCESS;
    CURL *curl = curl_easy_init();
    if(curl==NULL)
    {
    fprintf(stderr,"curl_easy_init err:%ld
    ",gCount);
    iRet = PROC_FAILED;
    return iRet;
    }
    struct curl_slist *http_header = NULL;
    http_header = curl_slist_append(http_header, "Accept: *");
    http_header = curl_slist_append(http_header, "Content-Type: application/xml");
    http_header = curl_slist_append(http_header, "Charset: utf-8");
    http_header = curl_slist_append(http_header, "User-Agent: HYB-HTTPCLI");
    
    curl_easy_setopt(curl,CURLOPT_URL,uri);
    curl_easy_setopt(curl,CURLOPT_POSTFIELDS,xml);
    curl_easy_setopt(curl,CURLOPT_POST,1);
    curl_easy_setopt(curl,CURLOPT_HTTPHEADER, http_header);//设置HTTP HEADER
    curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); //禁止产生信号(多线程时设置此选项)
    curl_easy_setopt(curl,CURLOPT_TIMEOUT,1L); //超时1s
    curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1); //完成后强制关闭连接
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
    fprintf(stderr,"CurlPost err:%s
    ",curl_easy_strerror(res));
    iRet = PROC_FAILED;
    }
    curl_slist_free_all(http_header);//http_header需要释放
    curl_easy_cleanup(curl);
    return iRet;
    }
    

    CURLOPT_POSTFIELDS选项的使用:

    如果是POST参数,填写参数即可,libcurl会将参数自动放到请求行中,比如:

    aa=12&bb=34

  • 相关阅读:
    Vue目录查询
    Vue框架学习(五)
    Vue框架学习(四)
    Vue框架学习(三)
    Vue框架学习(二)
    Vue框架学习(一)
    python中定义函数和参数的传递问题
    数据处理
    关于在程序中 文件新生成 在用os.system()程序对新生成的文件处理 举个栗子 如下:
    c++2008 并行配置文件和获取字典的所有key的方法
  • 原文地址:https://www.cnblogs.com/cqvoip/p/8078989.html
Copyright © 2020-2023  润新知