通过 Curl API 下载 libCurl 非常慢



我正在使用 CURL 库下载文件。我们正在使用带有TLS 1.2的 https://。 使用的 curl 版本是 7.48.0。我们正在观察一个奇怪的问题。对于 224 MB 的文件大小,服务器和客户端之间的 curl 下载速度非常慢。如果我们使用 curl 的命令行工具,它的速度非常快,但如果我们从应用程序端调用"curl_easy_perform",情况并非如此。

此外,我们使用 --libcurl 选项来检查命令行和我们的代码之间的差异,但没有。我们使用与命令行工具相同的选项,通过直接调用curl_easy_perform完成下载仍然非常慢。

如果我们从其他服务器和同一客户端下载,它可以正常工作。但是,只有对于特定的服务器,我们才会遇到下载时间问题。 进一步调试,我们发现 netstat 输出显示 tcp 套接字的接收队列非常高。但是,目前尚不清楚为什么这仅通过我们的程序而不是通过命令行成为问题,即使设置了相同的选项。

事实证明,问题是由于写回调,这需要此服务器的时间。在应用层的写回调用中,我们做了malloc,memcpy和自由复制收到的新数据。除了一台服务器外,所有服务器都可以正常工作。与此服务器连接的区别在于,Curl 在回调中给出 16378 个后跟 6 个字节的数据,而对于其他工作正常的服务器,它总是提供 16384 字节的数据。这与设备上默认为套接字缓冲区设置rmem_max大小相同。不知道为什么使用特定的服务器(Wildfly(,它会分解为16378字节,然后是6个字节。这导致连续的malloc,memcpy和224 MB文件大小下载的免费周期。因此,从套接字读取变得非常慢,导致下载速度变慢。在 Curl 命令行工具中,写回调的写入方式不同,其中打开文件并将数据写入该文件,方法是在接收数据时定期调用 fwrite,然后在接收所有数据后调用 fclose。与malloc,memcpy和自由操作相比,这是非常快速的操作。因此,curl 命令行工具适用于下载同一文件。我们更改了写入回调,使其与 curl 命令行的功能保持一致,它解决了问题。 但是,对于此特定服务器,Curl 将数据划分为 16378 + 6 字节的原因尚不清楚,我将进一步调查。

最新更新