c++ - libcurl : showing running upload and download rate

标签 c++ c callback libcurl

我有一个使用libcurl实现文件上传文件下载的类。 代码如下。

内存结构

    struct MemoryStruct {
    uint8_t* memory;
    size_t size;
  };

回调函数

size_t handleData(void* contents, size_t size, size_t nmemb, void* stream) {
    size_t realsize = size * nmemb;
    struct MemoryStruct* mem = static_cast<struct MemoryStruct*>(stream);

    uint8_t* ptr = static_cast<uint8_t*>(realloc(mem->memory, mem->size + realsize + 1));
    if (ptr == NULL) {
        return 0;
    }
    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;
    return realsize;
}

下载功能

bool download(const std::string& url, std::string& md5sum) {
        curl_off_t speed_download = 0;
        CURLcode res;
        struct MemoryStruct chunk{};

        chunk.memory = static_cast<uint8_t*>(malloc(1));
        if (nullptr == chunk.memory) {
            m_logger->errorf("malloc failed: Not enough memory");
            return false;
        }
        chunk.size = 0;

        res = curl_easy_setopt(m_curl, CURLOPT_URL, url.c_str());
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_setopt (CURLOPT_URL) failed: %s", curl_easy_strerror(res));
            free(chunk.memory);
            return false;
        }
        res = curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, handleData);
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_setopt (CURLOPT_WRITEFUNCTION) failed: %s", curl_easy_strerror(res));
            free(chunk.memory);
            return false;
        }
        res = curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, (void*) &chunk);
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_setopt (CURLOPT_WRITEDATA) failed: %s", curl_easy_strerror(res));
            free(chunk.memory);
            return false;
        }

        res = curl_easy_perform(m_curl);
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_perform() failed: %s", curl_easy_strerror(res));
            free(chunk.memory);
            return false;
        }

        std::vector<uint8_t> readData(chunk.memory, (chunk.memory + chunk.size));
        md5sum = md5AsHex(readData);

        res = curl_easy_getinfo(m_curl, CURLINFO_SPEED_DOWNLOAD, &speed_download);
        if (CURLE_OK != res) {
            m_logger->errorf("curl_easy_getinfo(CURLINFO_SPEED_DOWNLOAD) failed: %s", curl_easy_strerror(res));
            free(chunk.memory);
            return false;
        }
        m_logger->infof("Average download speed: %" CURL_FORMAT_CURL_OFF_T
                        "megabyte/sec.\n", speed_download / (1024 * 1024));
        free(chunk.memory);
        return true;
    }

上传功能

 bool upload(const std::string& filename, const std::string& url) {
    CURLcode res;
    curl_off_t speed_upload = 0;

    std::ifstream in(filename);
    std::string data_contents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());

    if (m_curl) {
        res = curl_easy_setopt(m_curl, CURLOPT_URL, url.c_str());
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_setopt(CURLOPT_URL) failed: %s", curl_easy_strerror(res));
            return false;
        }

        res = curl_easy_setopt(m_curl, CURLOPT_POSTFIELDS, data_contents.c_str());
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_setopt(CURLOPT_POSTFIELDS) failed: %s", curl_easy_strerror(res));
            return false;
        }

        res = curl_easy_setopt(m_curl, CURLOPT_POSTFIELDSIZE, (long) strlen(data_contents.c_str()));
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_setopt(CURLOPT_POSTFIELDSIZE) failed: %s", curl_easy_strerror(res));
            return false;
        }

        res = curl_easy_setopt(m_curl, CURLOPT_VERBOSE, 1L);
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_setopt(CURLOPT_VERBOSE) failed: %s", curl_easy_strerror(res));
            return false;
        }

        res = curl_easy_perform(m_curl);
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_perform() failed: %s", curl_easy_strerror(res));
            return false;
        }

        res = curl_easy_getinfo(m_curl, CURLINFO_SPEED_UPLOAD, &speed_upload);
        if (res != CURLE_OK) {
            m_logger->errorf("curl_easy_getinfo(CURLINFO_SPEED_UPLOAD) failed: %s", curl_easy_strerror(res));
            return false;
        }
        m_logger->infof("Average upload speed: %" CURL_FORMAT_CURL_OFF_T
                        " megabyte/sec.\n", speed_upload / (1024 * 1024));
        return true;
    }
    return false;
}

我想知道正在运行的下载/上传速率,以便我可以将其显示在屏幕上。在上面的示例中,我最后得到了上传下载速率。我想计算正在运行的上传和下载速率并显示类似进度条的内容。我该如何使用 libcurl 来做到这一点。

最佳答案

我建议您检查文档中的“CURLOPT_PROGRESSFUNCTION”。 您可以使用它轻松实现此类功能。

https://curl.haxx.se/libcurl/c/CURLOPT_PROGRESSFUNCTION.html

关于c++ - libcurl : showing running upload and download rate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59892606/

相关文章:

javascript - DOM 事件在事件队列中的优先级

c++ - asio::this_coro::executor 的实现是什么

c++ - 检测已知中心的部分隐藏椭圆的边界(OpenCV)

c - 在c中包含自定义头文件

c++ - 将 Matlab 变量传输到 C

c - C 语言中的字典/LUT 实现

javascript - 在回调函数中访问变量

ios - 在 iOS 7 中检测(收听)音频路由变化

C++ 简单计算输出 0.0000000000000000 而不是 0.003333

c++ - 关于后缀到中缀解析器的建议