【C++】开源:libcurl网络传输库配置与多线程下载器示例

news/2024/7/10 18:58:39 标签: c++, 开源, 网络

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍libcurl网络传输库配置与使用。
无专精则不能成,无涉猎则不能通。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

    • :smirk:1. 项目介绍
    • :blush:2. 环境配置
    • :satisfied:3. 使用说明
    • :satisfied:4. 多线程下载器示例

😏1. 项目介绍

项目Github地址:https://github.com/curl/curl

官网:https://curl.se/

libcurl 是一个功能强大、开源网络传输库,它支持多种协议,包括 HTTP、HTTPS、FTP、SMTP、POP3 等。libcurl 提供了一组易于使用的 API,可以用于在应用程序中进行网络通信。

下面是一些 libcurl 的主要特点和功能:

1.支持多种协议:libcurl 支持常用的网络协议,例如 HTTP、HTTPS、FTP、SMTP、POP3、IMAP 等,使开发者能够通过统一的接口处理各种网络传输需求。

2.容易集成:libcurl 提供了简洁易用的 C/C++ API,可以轻松地将其集成到各种应用程序中,无论是命令行工具还是图形界面应用。

3.多线程支持:libcurl 可以与多线程环境很好地配合使用,可以在多个线程中同时进行网络操作。

4.支持代理:libcurl 具有广泛的代理支持,可以配置和使用各种代理服务器进行网络传输。

5.SSL/TLS 加密支持:libcurl 内部集成了 OpenSSL 或者其他加密库,支持安全的 HTTPS 连接,保证数据的机密性和完整性。

6.断点续传:libcurl 允许断点续传功能,可以在网络连接中断后继续传输。

7.Cookie 支持:libcurl 具有完整的 Cookie 支持,可以处理和管理 Web 服务器发送的 Cookie。

8.自定义回调:libcurl 提供了回调函数接口,允许开发者自定义处理网络传输过程中的事件和数据。

9.跨平台:libcurl 可以在多个操作系统上运行,包括 Windows、Linux、macOS 等。

😊2. 环境配置

下面进行环境配置:

# apt安装开发包和依赖
sudo apt install libcurl4-openssl-dev

编译运行:

g++ -o main main.cpp -lcurl && ./main

😆3. 使用说明

下面进行使用分析:

libcurl 进行 HTTP 请求示例:

#include <iostream>
#include <curl/curl.h>

// 回调函数,用于处理下载的数据
size_t writeCallback(char* buf, size_t size, size_t nmemb, std::string* response) {
    size_t totalSize = size * nmemb;
    response->append(buf, totalSize);
    return totalSize;
}

int main() {
    CURL* curl;
    CURLcode res;

    // 初始化 libcurl
    curl_global_init(CURL_GLOBAL_DEFAULT);

    // 创建一个 curl 句柄
    curl = curl_easy_init();
    if (curl) {
        // 设置 URL ,自定义
        curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
        
        // 设置写回调函数
        std::string response;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        // 发送请求
        res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        } else {
            std::cout << "Response: " << response << std::endl;
        }

        // 清理 curl 句柄
        curl_easy_cleanup(curl);
    }

    // 清理 libcurl
    curl_global_cleanup();

    return 0;
}

FTP操作示例:

#include <iostream>
#include <curl/curl.h>

// 回调函数,用于处理接收到的 FTP 数据
size_t writeCallback(char* buf, size_t size, size_t nmemb, std::string* response) {
    size_t totalSize = size * nmemb;
    response->append(buf, totalSize);
    return totalSize;
}

int main() {
    CURL* curl;
    CURLcode res;

    // 初始化 libcurl
    curl_global_init(CURL_GLOBAL_DEFAULT);

    // 创建一个 curl 句柄
    curl = curl_easy_init();
    if (curl) {
        // 设置 FTP URL
        curl_easy_setopt(curl, CURLOPT_URL, "ftp://example.com/path/to/ftp/file.txt");

        // 设置用户名和密码(如果需要)
        curl_easy_setopt(curl, CURLOPT_USERPWD, "username:password");

        // 设置写回调函数
        std::string response;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        // 执行 FTP 下载操作
        res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        } else {
            std::cout << "FTP Response: " << response << std::endl;
        }

        // 清理 curl 句柄
        curl_easy_cleanup(curl);
    }

    // 清理 libcurl
    curl_global_cleanup();

    return 0;
}

断点续传示例:

#include <iostream>
#include <fstream>
#include <curl/curl.h>

// 回调函数,用于将下载的数据写入文件
static size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userdata) {
    std::ostream& stream = *static_cast<std::ostream*>(userdata);
    size_t totalSize = size * nmemb;
    stream.write(static_cast<const char*>(contents), totalSize);
    return totalSize;
}

int main() {
    const char* url = "http://example.com/file.txt";
    const char* outputFile = "file.txt";

    CURL* curl = curl_easy_init();
    if (curl) {
        // 检查之前的下载进度
        std::ifstream inputFile(outputFile, std::ios::binary);
        if (inputFile) {
            inputFile.seekg(0, std::ios::end);
            long long startPos = static_cast<long long>(inputFile.tellg());
            inputFile.close();

            if (startPos > 0) {
                std::string range = std::to_string(startPos) + "-";
                curl_easy_setopt(curl, CURLOPT_RANGE, range.c_str());
            }
        }

        // 设置 URL
        curl_easy_setopt(curl, CURLOPT_URL, url);

        // 设置写回调函数
        std::ofstream outputFileStream(outputFile, std::ios::binary | std::ios::app);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &outputFileStream);

        // curl_easy_perform 执行断点续传下载操作
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        } else {
            std::cout << "Download completed successfully." << std::endl;
        }

        // 清理 curl 句柄
        curl_easy_cleanup(curl);
    }

    return 0;
}

😆4. 多线程下载器示例

项目Github地址:https://github.com/tuyungang/http_multi_thread_download_tool

配置运行:

# 编译
cd xxx && make
# 下载示例(微信安装文件,200M左右)
./multi_thread_download -H https://dldir1.qq.com/weixin/Windows/WeChatSetup.exe -s 50

对比IDM多线程下载器(太好用辣),Linux也有axel等:

请添加图片描述

多线程下载器本质是自定义启动多个线程,分别下载文件的不同部分,最后将各个段拼接起来组成最后文件,中间文件删除,实现并行下载和分块下载的效果(libcurl支持了断点续传功能)。

在这里插入图片描述

以上。


http://www.niftyadmin.cn/n/4962378.html

相关文章

Lazada为什么成为卖家新宠?趋势如何?

其实跨境销售是网络发达以来,很多国内的商家都在突破的点。只有真正打开自己的市场,这样才可以让销售能够直线上升。如果永远在国内进行销售,那么不仅仅会增加难度,并且也很有可能无法打开自己的销售思路,导致最终在时代的潮流中没落。那么如果想要进行跨境销售,渠道就是相当重…

Spring参数注解,支持数组入参(List)校验

Spring参数注解&#xff0c;支持数组入参&#xff08;List&#xff09;校验 1、controller类增加Validated注解&#xff0c;对应的数组参数增加Valid注解。 Validated RestController RequestMapping("/parent") public class ParentController {private FatherRepos…

Spring Boot 整合MyBatis(超详细)

&#x1f600;前言 本篇博文关于Spring Boot 整合MyBatis&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x…

第三方软件测试都有哪些?

第三方软件测试 第三方软件测试是一种软件测试活动&#xff0c;旨在确保软件的质量、功能、性能和安全性等方面符合预期要求。 一、以下是一些常见的第三方软件测试类型&#xff1a; 兼容性测试&#xff1a;测试软件在不同操作系统、浏览器、数据库等环境下的兼容性。 功能测…

数字孪生在文物保护中的复原和展示

随着科技的迅猛发展&#xff0c;数字孪生技术正在逐渐引起文化遗产领域的重视。数字孪生作为一种虚拟仿真技术&#xff0c;不仅可以在虚拟环境中重现文物和遗产&#xff0c;还能为文物保护带来前所未有的创新和应用。本文带大家一起探讨数字孪生在文物保护方面的应用&#xff0…

查看mysql的最大连接数,并修改最大连接数

1、查看当前最大连接数 show variables like max_connections; mysql默认最大连接数为151&#xff0c;最大连接数为100000 通过命令修改最大连接数 set global max_connections1000;通过修改配置文件 修改my.cnf文件在 【mysqld】下面添加如下命令 max_connections1000

[ MySQL ] — 如何理解索引以及索引的操作

目录 初识索引 认识磁盘 MySQL与存储 了解磁盘 mysql与磁盘的交互 索引的理解 理解单个Page 理解多个Page 页目录 单页情况 多页情况 索引结构 - B树 聚簇索引 和 非聚簇索引 索引操作 创建主键索引 唯一索引的创建 ​编辑 普通索引的创建 全文索引的创建 查询…

Qt/C++开发经验小技巧281-285

悬停窗体QDockWidget默认在标题栏右键会弹出悬停模块的显示隐藏菜单&#xff0c;如果需要去掉&#xff0c;会发现设置Qt::NoContextMenu或者事件过滤器拦截都是无效的&#xff0c;必须设置 dockWidget->setContextMenuPolicy(Qt::PreventContextMenu); 。 Qt中的布局有个默…