zoukankan      html  css  js  c++  java
  • Curl的移植编译以及注意事项

         最近需要用curl来发送http请求,遇到了不少问题,查了不少资料,都是零零散散的,现在总结下。

         1、移植编译

          1 ./configure --prefix=$(PWD)/build --host=arm-XXX-linux;make ;make install 

          这步基本都没有问题,生成的动态链接库libcurl.a,可以直接给应用程序去使用。

        2、API使用

          1)全局初始化 curl_global_init(CURL_GLOBAL_ALL);

          2)通过curl_easy_init得到一个CURL指针m_pCurl

          3)通过curl_formadd封装参数

              通过curl_easy_setopt设置各种选项

             通过curl_easy_perform执行curl的各种操作

         4)curl_easy_getinfo 获得http返回的状态码

         5)curl_easy_cleanup释放CURL指针

         6)curl_global_cleanup释放全局对象

      3、http的响应内容获取

       先通过 curl_easy_setopt设置CURLOPT_WRITEFUNCTION,CURLOPT_WRITEDATA选项

    struct CResponseResult
    {
          int m_iResponseSize;                                // 响应的实际大小
          char* m_p_responseBuffer;                           // 指向响应内存的指针
    };

    size_t ReviceData(char *buffer, size_t size, size_t nmemb, CResponseResult & stream) { size_t total = size * nmemb;
        if (total <= 0 || (stream.m_iResponseSize + total) > MAX_RESPONSE_DATA_BUF_SIZE)
        {
            return 0;
        }

        memcpy(&stream.m_p_responseBuffer[stream.m_iResponseSize], buffer, total);
        stream.m_iResponseSize += total;
        return total; }
    // 每次发请求前,把buffer清空下
    memset(m_ResponseResult.m_p_responseBuffer, 0, MAX_RESPONSE_DATA_BUF_SIZE);
    m_ResponseResult.m_iResponseSize = 0;
    curl_easy_setopt(m_pCurl, CURLOPT_WRITEFUNCTION, ReviceData); curl_easy_setopt(m_pCurl, CURLOPT_WRITEDATA,
    &m_ResponseResult);

        当有响应回来的时候,会触发ReviceData函数,在这个回调函数,会把响应的内容,赋值给out变量,这样响应就取得了。

        4、遇到的一些问题

        curl_easy_setopt(m_pCurl, CURLOPT_CONNECTTIMEOUT, 4L);
        curl_easy_setopt(m_pCurl, CURLOPT_TIMEOUT, 25L);

        设置了超时时间后(一个是等待连接的时间,一个是等待接收响应的时间)一旦域名解析失败,程序会莫名的挂掉,而且每次挂掉的地方都不一样。当时也是通过一点一点注释代码,才定位到这两行代码。

        coredump的原因是因为curl的DNS解析超时控制是使用SIGALARM实现的。

        这样导致发现SIGALARM会出现多线程修改同一个全局变量,由此产生了COREDUMP。

        问题发生的前提是设置了CURLOPT_TIMEOUT或CURLOPT_CONNECTTIMEOUT,并且值不为0。

      解决办法:
       1) 设置CURLOPT_NOSIGNAL的值为1

        curl_easy_setopt(m_pCurl, CURLOPT_NOSIGNAL, 1);

         设置之后,发现的确不会coredump了,但是设置的超时时间没有用了,需要等很久,才能出结果。

     
       2) 使用c-ares(configure时指定参数--enable-ares)

        使用这个方法比较好,不会coredump,而且超时时间设置后生效。

        下面介绍下这个方法:

         a、下载cares的源码,进行编译移植

         https://c-ares.haxx.se/

         编译方法和curl的编译方法类似,都是通过configure ,最终生成libcares.a

        b、修改curl源码里的configure文件

         找到下面的代码,添加embedded_ares="yes",箭头所指的地方,不然check

    的时候,会报c-ares library defective or too old

       

         c、重新编译curl

    ./configure --enable-ares=$(PWD)/depends --prefix=$(PWD)/build --host=arm-XXX-linux;make ;make install

    这里指定了enable-ares使用的libares所在的目录。depends目录下需要再建立一个子目录lib,在子目录下放入libcares.a即可。

     还要把libcares的头文件都拷贝到curl主目录里的lib目录里,这样编译就不会出错了。

    高山流水,海纳百川!
  • 相关阅读:
    怎么样把网站logo(小图标)在地址栏里显示
    PHP 做群发短信(短信接口连接问题)
    网页JS弹出广告代码,头部,右下角,网页中漂浮,对联广告代码等大全
    PHP 时间戳与系统时间保持一致
    PHP 把数据表列出来的东西导出成execle格式
    数据库连接类 DB.class.php
    session判断页面是否已经登录的问题
    结合Smarty,生成HTML静态页
    PHP做文件下载功能
    滚动字幕,鼠标经过停留
  • 原文地址:https://www.cnblogs.com/ahcc08/p/11656395.html
Copyright © 2011-2022 走看看