如何避免libcurl的https多线程问题:
(1)在post或get封装(就是从libcurl请求到收到回复整个过程的封装)里加一把大锁,锁住与libcurl相关的所有https请求
(2)使用的libcurl支持ssl用到的openssl的版本必须在1.1.x或以上(已经解决线程安全问题)
(3)如果编译的openssl版本在1.0.x以下,网络上还有一种处理方式就是设置一个回调,具体参考网络文章
针对第一种,就是效率问题,如果加一把大锁,我为何还用多线程处理http或https消息,交给一个线程做就可以了,但是我们一般不会这么干;第二种就必须编译openssl1.1.x以上依赖库。
版本:OpenSSL openssl-1.1.0c.tar.gz版本
curl版本 curl-7.57.0.tar.gz
准备开始交叉编译OpenSSL
在openssl解压目录下,使用config命令
CC=arm-linux-gcc ./config no-asm shared --prefix=/home/linux/arm/openssl --openssldir=/home/linux/arm/openssl/ssl
生成了Makefile
然后就是make和make install;之后会在安装目录下生成lib文件
一、安装openssl
1、下载 openssl https://www.openssl.org/source/
2、解压 $ tar -xvf openssl-1.1.0i.tar.gz
3、查看源代码中的 INSTALL 文档,按照指示步骤编译 openssl$
./config
$ make
$ make test (optional)
$ make install
备注:
其中第 3 步可以省略,第 4 步需要 root 权限。
如果要编译动态库,需要增加参数如下:./config no-asm --shared
此时,查看 openssl 可以看到变化:
3、生成的文件目录在:/usr/local/lib/会产生libcrypto.a和libssl.a
头文件在:/usr/local/include 下
库文件在:/usr/local/lib 下
二、安装curl
安装 openssl 结束后,我们重新按照 libcurl 源代码中的 docs 文件夹中的 INSTALL 文件中的指示编译 libcurl 即可
1、下载文件并解压 curl-7.53.1.tar.gz
http://curl.haxx.se/download.html
解压缩之后的文件夹中有3个比较重要的目录:docs、lib和src,其中,docs中包括项目的所有相关文档,lib中为libcurl库的源码,src为curl命令行工具的源码。
2、执行
$ ./configure --host=arm-oe-linux-gnueabi --with-ssl --enable-static
$ make
$ make test (optional)
$ make install
其中第 3 步可以省略,第 4 步需要 root 权限。
当你运行完第 1 步的时候,也就是 configure 执行完之后,如果 openssl 安装没有问题的话,应该就能看到 SSL 的支持了:
3、生成的文件目录
头文件在:/usr/local/include 下
库文件在:/usr/local/lib 下会产生libcurl.a、libcurl.la、libcurl.so、libcurl.so.4、libcurl.so.4.5.0
4、curl-config --feature查询
三、静态编译bin
当你编译程序时, 碰到下面的链接错误,
timeval.c:(.text+0x6f): undefined reference to `clock_gettime'则你只需要在你的Makefile文件里面添加-lrt,重新编译即可。
在程序中静态链接 这个 libcurl.a 文件, 会发生很多的链接错误, 如果是动态链接 libcurl.a 文件则不会发生什么问题。
/usr/lib/libcurl.a(ssluse.o): In function `Curl_ossl_init':
(.text+0xcd1): undefined reference to `SSL_library_init'
/usr/lib/libcurl.a(ssluse.o): In function `Curl_ossl_connect_common':
(.text+0x1ba9): undefined reference to `SSL_get1_session'
只需要添加下面的链接,
-lcurl -lcrypto -lssl
如果你用上面的选项还是出现链接错误,比如下面
ldap.c:(.text+0x91): undefined reference to `ldap_url_parse'
请你编译 curl库的时候 用下面的指令生成 makefile文件
--disable-ldap --disable-ldaps
libcurl.a静态库,需要配合ssl,crypto 一起使用,否则在编译的时候,会报很多未识别的错误。一般情况下,可以直接通过控制 libcurl.a的编译选项,取消不需要的库,如:
./configure --without-ssl --disable-ldap --without-nss --without-libssh2 --enable-static
收到回调的curl_easy,不能直接给释放掉,需要先加到队列中,一起释放,先从multi中移除easy句柄,调用curl_multi_remove_handle然后在释放easy空间,调用curl_easy_cleanup
四、小结
cURL 这个项目包含了 libcurl 和 curl 两个产品。
其中,libcurl 是一个客户端的 URL 支持库;而 curl 就是一个使用了 libcurl 库写出来的命令行工具,其可以使用 URL 标识来请求或者发送文件。
其中 cURL、libcurl 以及 curl 三者之间的关系如下图所示