转自:
http://gcoder.blogbus.com/logs/54871550.html
http://blog.csdn.net/balderfan/article/details/7599554
(1), 超时(timeout)
libcurl 是 一个很不错的库,支持http,ftp等很多的协议。使用库最大的心得就是,不仔细看文档,仅仅看着例子就写程序,是一件危险的事情。我的程序崩溃了,我 怀疑是自己代码写的问题,后来发现是库没用对。不仔细看文档(有时候文档本身也比较差劲,这时除了看仔细外,还要多动脑子,考虑它是怎么实现的),后果很 严重。不加思索的使用别人的库或者代码,有时候很惬意,但是出问题时,却是寝食难安的。
1. CURLcode curl_global_init(long flags); 在多线程应用中,需要在主线程中调用这个函数。这个函数设置libcurl所需的环境。通常情况,如果不显式的调用它,第一次调用 curl_easy_init()时,curl_easy_init 会调用 curl_global_init,在单线程环境下,这不是问题。但是多线程下就不行了,因为curl_global_init不是线程安全的。在多个线 程中调用curl_easy_int,然后如果两个线程同时发现curl_global_init还没有被调用,同时调用 curl_global_init,悲剧就发生了。这种情况发生的概率很小,但可能性是存在的。
2. libcurl 有个很好的特性,它甚至可以控制域名解析的超时。但是在默认情况下,它是使用alarm + siglongjmp 实现的。用alarm在多线程下做超时,本身就几乎不可能。如果只是使用alarm,并不会导致程序崩溃,但是,再加上siglongjmp,就要命了 (程序崩溃的很可怕,core中几乎看不出有用信息),因为其需要一个sigjmp_buf型的全局变量,多线程修改它。(通常情况下,可以每个线程一个 sigjmp_buf 型的变量,这种情况下,多线程中使用 siglongjmp 是没有问题的,但是libcurl只有一个全局变量,所有的线程都会用)。
具体是类似 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L) 的超时设置,导致alarm的使用(估计发生在域名解析阶段),如前所述,这在多线程中是不行的。解决方式是禁用掉alarm这种超时, curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L)。
这样,多线程中使用超时就安全了。但是域名解析就没了超时机制,碰到很慢的域名解析,也很麻烦。文档的建议是 Consider building libcurl with c-ares support to enable asynchronous DNS lookups, which enables nice timeouts for name resolves without signals. c-ares 是异步的 DNS 解决方案。
调用libcurl下载,然后使用netstat查看发现有大量的TCP连接保持在CLOSE_WAIT状态
查看libcurl的文档说明,有这样一个选项:
CURLOPT_FORBID_REUSE
Pass a long. Set to 1 to make the next transfer explicitly close the connection when done. Normally, libcurl keeps all connections alive when done with one transfer in case a succeeding one follows that can re-use them. This option should be used with caution and only if you understand what it does. Set to 0 to have libcurl keep the connection open for possible later re-use (default behavior).
也就是说,默认情况下libcurl完成一个任务以后,出于重用连接的考虑不会马上关闭
如果没有新的TCP请求来重用这个连接,那么只能等到CLOSE_WAIT超时,这个时间默认在7200秒甚至更高,太多的CLOSE_WAIT连接会导致性能问题
解决方法:
curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);
最好再修改一下TCP参数调低CLOSE_WAIT和TIME_WAIT的超时时间
分享到:
相关推荐
基于libcurl/pthreads的多线程下载器,跨平台,支持暂停、还原、中止,断点续传,支持HTTP,HTTPS协议链接,http://blog.csdn.net/u012532305/article/details/46709495也是这篇文章的源码
基于libcurl/pthreads的多线程下载器,跨平台,支持暂停、还原、中止,断点续传,支持HTTP,HTTPS协议链接,http://blog.csdn.net/u012532305/article/details/46709495也是这篇文章的源码,此版本修复上一版本发现的...
基于Qt5和libcurl实现的c++多线程文件下载器,具有限速下载和下载管理等功能
基于libcurl实现http post支持并发,异步 方便新手学习
iOS开发 libcurl库的简单使用
libcurl库开发手册,有利于初入libcurl库开发人员进行网络上传下载的开发环境的搭建,快速入手的基础篇
摘要视图订阅登录 | 注册1049340次第622名160篇562篇3篇97条关于使用libcurl的注意事项 blade2001的专栏 博客频道
本人自己原创的解决libcurl单线程阻塞卡死问题解决的方案及源代码
libcurl是一个跨平台的开源网络协议库,支持http, https, rtsp等多种协议 。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证。
最近遇到项目,对数据传输的安全性要求不高,需要C++用post方法调用ASP.NET Web Service,开始有人推荐用gsoap,后来自己网上搜索发现用libcurl库完全够用,由于我是windows下开发,所以花功夫编译了windows版的...
libcurl功能和使用介绍 在libcurl使用方法介绍,libcurl 是主要进行网络数据下载编程的函数
个人编译的 libcurl静态库,并且附带使用例子!
libcurl使用Https说明,使用此文档里面有资源。帮助开发基于SOCKET的HTTPS传输协议。(描述可能不详)
libcurl
个人编译的 libcurl静态库,并且附带使用例子,改下IP地址就能用
c++使用libcurl上传和下载资源,封装了库,带lib文件,带nodejs测试服务端
libcurl库的安装和使用111
libcurl使用demo,根据一个网址,获取它的http头信息,然后解析其中的属性值
libcurl的简单使用,C++,内附下载链接