转自:
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的注意事项 libcurl是一个强大的库,支持多种网络协议,如HTTP、FTP等。在使用libcurl时,需要注意以下几点以确保程序的稳定性和效率: 1. 关闭连接重用(CLOSE_WAIT问题): 默认情况下,libcurl...
- libcurl使用非阻塞I/O,因此在多线程应用中需正确管理线程安全。 - 使用HTTPS时,确保正确配置SSL证书和验证机制。 - 对于IPv6支持,如果不需要,可以关闭以减少潜在的问题。 - 私信作者询问使用问题,意味着社区...
8. **注意事项** - 记得在项目设置中链接 libcurl.lib。 - 如果服务器需要身份验证,可以通过 `CURLOPT_USERPWD` 设置用户名和密码。 - 文件上传可能涉及 POST 数据,如表单字段。可以使用 `CURLOPT_...
文档主要针对使用libcurl的人员,讨论了在应用程序开发过程中的正确使用方法和注意事项。 1. 初始化和清理 在使用libcurl之前,必须先初始化libcurl。Libcurl只需初始化一次,可以使用以下语句进行初始化:`curl_...
- 在“配置属性”>“C/C++”>“代码生成”中,设置“运行时库”为“多线程DLL”或“多线程”,取决于你选择的动态库还是静态库。 6. **编译和链接**: - 保存所有更改,然后尝试编译和链接项目。如果出现错误,...
- **线程安全**:在多线程环境中使用libcurl时,需要正确配置线程安全选项。 - **版本兼容性**:确保你的libcurl_imp.lib与你的其他依赖库和编译器版本兼容。 通过理解和熟练使用libcurl_imp.lib,开发者可以构建...
- **安全注意事项**:在从不可信来源下载libcurl32.dll时,要确保文件的来源安全,避免病毒或恶意软件的威胁。安装后,如果问题仍未解决,可能需要检查其他依赖项或系统设置。 总的来说,libcurl32.dll是libcurl库...
例如,如果你的应用程序使用了多线程并且链接到静态 C++ 运行库,那么 Libcurl 也应该如此。通常,对于静态链接,你可能需要设置 `-DCURL_STATICLIB` 预处理器宏。 在某些环境下,可能还需要配置其他选项,例如 SSL...
1. 多线程支持:libcurl支持多线程,但需注意线程安全问题。 2. 缓存策略:合理设置缓存策略可以提高性能,减少网络请求。 3. 错误排查:遇到问题时,开启libcurl的日志功能,通过日志分析定位问题。 总结,libcurl...
例如,如果libcurl是使用多线程静态链接(MT)编译的,那么项目也应该配置为使用相同的运行时库。 **代码示例** 下面是一个简单的C++代码示例,展示了如何使用libcurl发起一个HTTP GET请求: ```cpp #include ...
6. **注意事项**: - 资源管理:确保正确地添加和移除cURL句柄,避免资源泄漏。 - 并发控制:过多的并发请求可能会导致服务器压力过大,需要合理设置并发数。 - 错误处理:必须处理因网络问题、服务器错误或其他...
3. C++:C++标准库中的std::thread和std::future可以用来实现多线程,而libcurl库则用于处理网络请求。 四、优化策略 1. 并行度调整:根据网络状况和系统资源动态调整并发下载的线程数量,以达到最佳性能。 2. 块...
四、优化与注意事项 - 线程池:为了防止频繁创建和销毁线程的开销,可以使用线程池来复用线程。 - 错误处理:确保处理网络错误,如超时、断线重连等。 - 并发控制:根据网络条件调整并发下载的线程数量,避免过度...
- **多线程支持**:利用`curl_multi_init()`等函数实现多线程下载或上传。 - **自定义回调函数**:可以注册自己的回调函数来处理数据读写或其他事件。 - **性能优化**:通过设置合适的选项(如连接超时、重试策略等...
它支持多线程,可以设置超时、代理、重定向、cookies、认证等多种特性,还支持SSL加密,使得数据传输更加安全。 **使用libcurl.lib的步骤:** 1. **下载与解压**:首先,下载这个名为“libcurl”的压缩包,并将其...
2. **线程安全**:如果在多线程环境中使用libcurl,需确保对共享资源的操作是线程安全的。 3. **超时设置**:设置合理的超时限制,防止请求无限期等待。 4. **错误处理**:及时捕获并处理libcurl返回的错误码,确保...
- 记得根据实际需求调整编译选项,比如选择支持哪些协议、是否启用多线程等。 - 保持库版本与所依赖的其他库版本兼容,避免出现兼容性问题。 这个过程可能需要一定的耐心和对编译工具的理解,但一旦完成,你将...
注意管理libcurl分配的内存,并确保在多线程环境下正确使用和初始化libcurl。 8. **示例代码**: 以下是一个简单的示例,展示了如何使用libcurl进行HTTP GET请求: ```c #include #include static size_t...
8. **安全注意事项**:在使用`curl`处理HTTPS请求时,确保正确处理证书验证,避免中间人攻击。可以设置`CURLOPT_SSL_VERIFYPEER`和`CURLOPT_SSL_VERIFYHOST`选项来控制证书验证行为。 9. **版本更新**:`android_...
4. 并发处理:为了提高效率,可使用多线程或多进程技术,如pthread库或fork系统调用,同时处理多个URL请求。 5. 循环爬取:设计一个递归或层次结构的爬取逻辑,根据提取到的新链接继续爬取下一层网页。 五、注意...