首页 > 解决方案 > LibCurl : curl_multi_perform 在处理请求时不一致

问题描述

我对 libcurl 很陌生。所以任何帮助表示赞赏。

我正在尝试从 CDN 下载多个文件。总大小约为600mb。这是我设置 CURL 句柄的一段代码(在名为“addTransfers()”的方法内)。(cm 是 CURLM* 类型)

CURL *ceh = curl_easy_init();
curl_easy_setopt(ceh, CURLOPT_URL, reqURL.c_str());
curl_easy_setopt(ceh, CURLOPT_USERPWD, usrpwd);
curl_easy_setopt(ceh, CURLOPT_WRITEDATA, file);
curl_easy_setopt(ceh, CURLOPT_PRIVATE, file);
curl_easy_setopt(ceh, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(ceh, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt(ceh, CURLOPT_CONNECTTIMEOUT, 10L);
curl_easy_setopt(ceh, CURLOPT_TIMEOUT, 150L);

curl_multi_add_handle(cm, ceh);

这是我执行 curl 多进程的代码:

bool do_multiple_downloads()
{
    CURLM *cm;
    CURLMsg *msg;
    unsigned int transfers = 0;
    int pending = 1;
    int msg_pending = -1;

    curl_global_init(CURL_GLOBAL_ALL);
    cm = curl_multi_init();

    curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, maxConnects);

    for(transfers = 0; transfers < (int)maxConnects; transfers++)
    {
        if(!addTransfers(cm, transfers))
        {
            //Error
            return false;
        }
    }

    int i = 0;

    do
    {
        /* code */
        CURLMcode cPerformCode = curl_multi_perform(cm, &pending);
        if(cPerformCode != CURLM_OK)
        {
            fprintf(stderr, "Error --> (%s) : Pending --> (%d)", curl_multi_strerror(cPerformCode), pending);
            return false;
        }
        while((msg = curl_multi_info_read(cm, &msg_pending))) 
        {
            if(msg != NULL)
            {
                if(msg->msg == CURLMSG_DONE)
                {
                    FILE* writtenFile;
                    char* fname;
                    CURL *e = msg->easy_handle;

                    curl_easy_getinfo(e, CURLINFO_PRIVATE, &writtenFile);
                    fprintf(stderr, "R: %d - %s (%d)\n",
                            msg->data.result, curl_easy_strerror(msg->data.result), i++);

                    curl_multi_remove_handle(cm, e);
                    fclose(writtenFile);
                    curl_easy_cleanup(e);
                }
                else
                {
                    fprintf(stderr, "E: CURLMsg (%d) : (%d)\n", msg->msg, i++);
                }
                if(transfers < totalSize)
                {
                    if(!addTransfers(cm, transfers++))
                    {
                        //Error
                        fprintf(stderr, "Additional transfers addition\n");
                        return false;
                    }
                }
            }
        }
        if(pending)
        {
            curl_multi_wait(cm, NULL, 0, 1000, NULL);
        }

    } while (pending || (transfers < totalSize));

    curl_multi_cleanup(cm);
    curl_global_cleanup();

    return true;
}

这些是场景:

  1. 有时它工作正常并且所有文件都已下载 - 没问题
  2. 有时下载已完成,但程序仍在 do-while 循环中(未决变量永远不会变为零)
  3. 如果我在进程发生时断开互联网连接,程序将停留在 do-while 循环中。当我重新连接到互联网时,会出现场景 2。

我在这里错过了什么吗?我可能在这里做了一些愚蠢的事情。不过不确定。提前致谢。

标签: c++libcurl

解决方案


推荐阅读