zoukankan      html  css  js  c++  java
  • 使用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

  • 相关阅读:
    Apache+php在windows下的安装和配置
    我的mac的其他满了,发现是一个叫core的文件
    如何去掉drwxr-xr-x@中的@符号Linux文件扩展信息
    Wireshark使用教程
    nano 编辑
    sed: 1: “…”: invalid command code on Mac OS
    wireshark error: There are no interfaces on which a capture can be done.
    mac os x10.9.2 查看进程对应端口
    Mac下安装LNMP(Nginx+PHP5.6)环境
    Web实现浏览器端大文件分片上传
  • 原文地址:https://www.cnblogs.com/cqvoip/p/8078989.html
Copyright © 2011-2022 走看看