C ++ Libcurl curl_easy_getinfo在CURLOPT_XFERINFOFUNCTION函数中不返回任何内容

时间:2017-08-13 18:47:10

标签: c++ libcurl

我有一个使用LibCurl上传文件的应用程序。我用下面的函数显示上传进度和百分比,效果很好。但是,我无法获得CURLINFO_SPEED_UPLOAD函数的平均上传速度(CURLINFO_TOTAL_TIME)和经过的时间(curl_easy_getinfo)。我在这做错了什么?我与Libcurl的原始示例有很多不同之处?

static int ReceiveFileProgress(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) {
    if (ultotal > 0) {
        string Output;
        double curtime = 0;
        char ulspeed[10000];
        double ulspeed_curl = 0;
        double ulnow_db = (double)ulnow;
        double ultotal_db = (double)ultotal;
        double percentage = ceil((ulnow_db / ultotal_db) * 100);
        struct myprogress *myp = (struct myprogress *)p;
        CURL *curl = myp->curl;
        if (curl) {
            cout << "CURL OK" << endl;
            }
        else {
            cout << "CURL FAILED" << endl;
            }
        if (percentage != 100) {
            curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &ulspeed_curl);
            }
        curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);
        readable_fs(ulspeed_curl, ulspeed);
        stringstream OutputStream;
        OutputStream << percentage;
        Output = PadString(OutputStream.str(), 3, " ");
        OutputStream.str("");
        OutputStream << Output << "%";
        if (percentage != 100) {
            OutputStream << " (" << ulspeed << "/s)";
            }
        Output = OutputStream.str();
        if (Output.length() > SendOffFileMaxProgressLength) {
            Output.substr(0, SendOffFileMaxProgressLength - 3);
            Output += "...";
            }
        else {
            while (Output.length() < SendOffFileMaxProgressLength) {
                Output += ' ';
                }
            }
        cout << Output << '\r';
        }
    return 0;
    }

卷曲请求:

string PerformCurlRequest(string RequestType, struct curl_httppost &formpost, struct curl_httppost &lastptr) {
    CURL *curl;
    CURLcode res;
    bool UsedProxy;
    string CurlResponse;
    int LibCurlError = 0;
    int ProxyRetryCount = 1;
    bool TryWithProxy = true;
    struct curl_slist *LibcurlHeaders = NULL;
    curl = curl_easy_init();
    if (curl) {
        host = "url/";
        host += RequestType;
        host += "/";
        LibcurlHeaders = curl_slist_append(LibcurlHeaders, "Expect:");
        curl_easy_setopt(curl, CURLOPT_URL, (host).c_str());
        curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, LibcurlHeaders);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, CurlVerbose);
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, LibcurlResponse);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &CurlResponse);
        curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, GetCurlVerboseData);
        curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, ReceiveFileProgress);
        curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progress);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false);
        res = curl_easy_perform(curl);
        curl_slist_free_all(LibcurlHeaders);
        curl_easy_cleanup(curl);
        }
    return CurlResponse;
    }

发送文件:

PerformCurlRequest("SendFile", *formpostReceiveFile, *lastptrReceiveFile)

1 个答案:

答案 0 :(得分:1)

我不知道你正在使用什么libcurl版本,或者你是否可能在其他地方弄乱你的代码,但是我可以从这个示例代码中的libcurl进程回调中做CURLINFO_SPEED_UPLOAD做HTTP“上传“(为简单起见,在这里使用PUT):

#include <stdio.h>
#include <curl/curl.h>
#include <sys/stat.h>

struct myprogress {
  CURL *curl;
};

static int xferinfo(void *p, curl_off_t dltotal, curl_off_t dlnow,
                    curl_off_t ultotal, curl_off_t ulnow)
{
  struct myprogress *myp = (struct myprogress *)p;
  CURL *curl = myp->curl;
  double ulspeed_curl = 0;

  curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &ulspeed_curl);

  fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
          "  DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
          " AVRUP: %.1f"
          "\r\n",
          ulnow, ultotal, dlnow, dltotal, ulspeed_curl);

  return 0;
}

/* send off a random test file lying around */
#define FILENAME "file-to-send"

int main(void)
{
  CURL *curl;
  CURLcode res = CURLE_OK;
  struct myprogress prog;

  curl = curl_easy_init();
  if(curl) {
    FILE *strace;
    struct stat file_info;
    prog.curl = curl;

    strace = fopen(FILENAME, "rb");
    if(!strace)
      return 1;

    /* get the file size of the local file */
    stat(FILENAME, &file_info);

    curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/");
    curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
    curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
                     (curl_off_t)file_info.st_size);
    curl_easy_setopt(curl, CURLOPT_READDATA, strace);
    res = curl_easy_perform(curl);

    if(res != CURLE_OK)
      fprintf(stderr, "%s\n", curl_easy_strerror(res));

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  return (int)res;
}