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

  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目录里,这样编译就不会出错了。

Curl的移植编译以及注意事项的更多相关文章

  1. Qt 5.8 移植编译、测试

    /****************************************************************************** * Qt 5.8 移植编译.测试 * 说 ...

  2. 【计算机视觉】关于OpenCV中GPU配置编译的相关事项

    [计算机视觉]关于OpenCV中GPU配置编译的相关事项 标签(空格分隔): [计算机视觉] 前一段发现了OpenCV中关于GPU以及opencl的相关知识,打算升级一下对OpenCV的使用,但是发现 ...

  3. FFmpeg的Android平台移植—编译篇

    摘要:本文主要介绍将FFmpeg音视频编解码库移植到Android平台上的编译和基本测试过程. 环境准备: ubuntu-12.04.5 android-ndk64-r10-linux-x86_64. ...

  4. uboot-2012.04.01移植编译前准备

    一:准备移植1.从下面的官网下载uboot-2012.04.012.建立sourceinsight工程 a.解压并在E:\colin weidongshan\transplant_u-boot-201 ...

  5. Mac openssl 和curl源码编译

    1.先编译openssl, 下载源码后解压,终端进入源码目录,输入命令配置编译环境:./Configure darwin64-x86_64-cc 等待配置完成后,输入make  和make insta ...

  6. libx264开发笔记(一):libx264介绍、海思平台移植编译

    前言   在编译ffmpeg时,使用到h264编码时是需要依赖libx264的,本文章是将将libx264作为静态库移植到海思上.   相关博客 <Qt开发笔记之编码x264码流并封装mp4(一 ...

  7. curl开源库编译

    环境:Win7+VS2013 1.下载curl的zip包并解压,本文下载的是curl-7.39.0.zip,下载地址:http://curl.haxx.se/download.html 2.打开vs2 ...

  8. android 编译代码注意事项

    1 安装openjdk1.7 sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-apt update sudo apt-get install op ...

  9. python 安装预编译库注意事项-pip

    一般安装依赖库用pip install 库名 就可以,某些情况下依赖的库需要安装预编译好的, 可以参考pip 安装时的错误信息 下面这个链接中可以直接下载 http://www.lfd.uci.edu ...

随机推荐

  1. “玲珑杯”ACM比赛 Round #18 1147 - 最后你还是AK了(思维,边的贡献)

    题目链接:http://www.ifrog.cc/acm/problem/1147 题解:这题很容易想到的是边的贡献也就是每条边最多被取到几次,和点的贡献类似,那些加边只要加在边贡献大的边上就行.然后 ...

  2. Docker笔记(十):使用Docker来搭建一套ELK日志分析系统

    一段时间没关注ELK(elasticsearch —— 搜索引擎,可用于存储.索引日志, logstash —— 可用于日志传输.转换,kibana —— WebUI,将日志可视化),发现最新版已到7 ...

  3. Day003_Linux基础——系统目录结构

    Linux系统的目录结构: 圆型节点代指目录,方型节点代指文件. 图中省去了很多不常用的目录与文件. 稍后单独讲/proc目录与/var目录. /usr 目录. /usr/local 用户个人安装的软 ...

  4. 解开Batch Normalization的神秘面纱

    停更博客好长一段时间了,其实并不是没写了,而是转而做笔记了,但是发现做笔记其实印象无法更深刻,因此决定继续以写博客来记录或者复习巩固所学的知识,与此同时跟大家分享下自己对深度学习或者机器学习相关的知识 ...

  5. Go语言基础之文件操作

    本文主要介绍了Go语言中文件读写的相关操作. 文件是什么? 计算机中的文件是存储在外部介质(通常是磁盘)上的数据集合,文件分为文本文件和二进制文件. 打开和关闭文件 os.Open()函数能够打开一个 ...

  6. Mysql使用SSL连接

    最近项目中用到了SSL连接,记录一下,环境为windows10,Mysql版本为5.6 查看是否支持 SSL 首先在 MySQL 上执行如下命令, 查询是否 MySQL 支持 SSL: mysql&g ...

  7. 本地代码上传github失败常见错误

    1.上传失败 解决办法如下: 可以通过如下命令进行github与本地代码合并: git pull --rebase origin master 重新执行上传命令: git push -u origin ...

  8. Docker Compose部署项目到容器-基于Tomcat和mysql的项目yml配置文件代码

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  9. 创建进程池与线程池concurrent.futures模块的使用

    一.进程池. 当并发的任务数量远远大于计算机所能承受的范围,即无法一次性开启过多的任务数量就应该考虑去 限制进程数或线程数,从而保证服务器不会因超载而瘫痪.这时候就出现了进程池和线程池. 二.conc ...

  10. js-数据交互--AJAX

    一:介绍 今天跟下大家简单的介绍一下,在前端开发中,前后端数据交互的一种手段,我们都知道,在前端往后端传送数据的话,利用get,post方法即可向后端发送数据,后端将数据接受,链接到数据库,进行数据库 ...