C 言語は libcurl ライブラリを呼び出して Linux でファイルをローカルにダウンロードします

1. プロジェクト紹介

この記事では、C 言語を使用して libcurl ライブラリを呼び出し、Linux (Ubuntu) オペレーティング システムでネットワーク ファイル ダウンロード機能を実装する方法を紹介します。

libcurlは、さまざまなネットワーク通信プロトコルのクライアント機能をCやC++などのプログラミング言語で実装するためのオープンソースのクロスプラットフォームネットワーク伝送ライブラリです。HTTP、HTTPS、FTP、SMTP、POP3などのさまざまなプロトコルをサポートしており、データのアップロードおよびダウンロード操作を簡単に実行できます。

画像-20230626101116409

以下に、libcurl ライブラリの主な特徴と機能をいくつか示します。

1. 跨平台性:libcurl库可以在多个操作系统上使用,包括Windows、Linux、macOS等。这使得开发者可以轻松地编写跨平台的网络应用程序。
2. 多协议支持:libcurl支持多种网络协议,包括HTTP、HTTPS、FTP、SMTP、POP3等。它提供了丰富的API,使得开发者可以通过简单的接口调用来实现与远程服务器之间的通信。
3. 断点续传:libcurl支持断点续传功能,即可以从已经下载的位置继续下载文件。这对于大文件的下载非常有用,可以节省带宽和时间,并避免重新下载整个文件。
4. SSL/TLS支持:libcurl可以通过OpenSSL或其他TLS/SSL库来进行安全传输。它支持HTTPS协议,并提供了SSL证书验证、加密和解密等功能,以确保数据的安全性。
5. 异步和多线程支持:libcurl提供了异步和多线程操作的支持,可以在网络传输过程中进行其他任务处理,提高程序的并发性和性能。
6. 适应性和灵活性:libcurl库提供了丰富的选项和回调函数,允许开发者根据自己的需求进行定制和扩展。开发者可以配置代理服务器、设置超时时间、自定义HTTP头部等。
7. 良好的错误处理和调试支持:libcurl提供了详细的错误代码和错误信息,方便开发者进行错误处理和故障排除。它还提供了调试输出功能,可打印详细的网络通信和传输信息。
8. 并发连接管理:libcurl支持并发连接管理,可以同时处理多个网络请求。这对于高并发的网络应用非常有用,可以提高系统的吞吐量和性能。

2. 環境整備

**libcurl library:** は、ターミナルで次のコマンドを実行することでインストールできます。

sudo apt-get install libcurl4-openssl-dev

GitHub リポジトリ: https://github.com/curl/curl
libcurl 公式 Web サイト: https://curl.se/libcurl/

3. 設計手順

3.1 ヘッダーファイルのインポート

C コード ファイルでは、curl/curl.hlibcurl ライブラリが提供する関数と構造体を使用するためにヘッダー ファイルを導入する必要があります。

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

3.2 libcurlの初期化

プログラムを開始する前に、libcurl ライブラリを初期化する必要があります。curl_global_initこれは関数を呼び出すことで実行できます。

curl_global_init(CURL_GLOBAL_DEFAULT);

3.3 ダウンロード オプションの設定

次に、ダウンロードする URL リンク、ローカルに保存するファイル パスなどのダウンロード オプションを設定する必要があります。オプションは関数を使用して設定できますcurl_easy_setopt

CURL *curl = curl_easy_init();
if (curl) {
    
    
    curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/file.zip");
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);  // fp是文件指针,用于保存下载的数据
}

3.4 ダウンロードリクエストの実行

関数を呼び出してcurl_easy_performダウンロード要求を実行し、指定されたパスにファイルを保存します。実行中、libcurl ライブラリはネットワーク転送とファイル データの受信を自動的に処理します。

CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
    
    
    fprintf(stderr, "下载失败: %s\n", curl_easy_strerror(res));
}

3.5 リソースのクリーンアップ

最後に、プログラムの最後に、libcurl のリソースをクリーンアップする必要があります。curl_easy_cleanupこれは関数を呼び出すことで実行できます。

curl_easy_cleanup(curl);

3.6 完全なサンプルコード

以下は、C 言語と libcurl ライブラリを使用して、Linux (Ubuntu) でネットワーク ファイル ダウンロード機能を実装する方法を示す完全なサンプル コードです。

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

int main() {
    
    
    CURL *curl = curl_easy_init();
    FILE *fp = fopen("downloaded_file.zip", "wb");  //打开一个文件用于保存下载的数据

    if (curl && fp) {
    
    
        curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/file.zip");
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);

        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
    
    
            fprintf(stderr, "下载失败: %s\n", curl_easy_strerror(res));
        }

        fclose(fp);
    } else {
    
    
        fprintf(stderr, "初始化失败\n");
    }

    curl_easy_cleanup(curl);
    curl_global_cleanup();

    return 0;
}

3.7 コンパイルと実行

ターミナルで、次のコマンドを使用してサンプル コードをコンパイルします。

gcc -o download_program download_program.c -lcurl

次に、結果の実行可能ファイルを実行してダウンローダーを実行します。

./download_program

4. 完全なコード

以下は、ネットワーク ファイル ダウンロード機能をカプセル化するサブ関数です。

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

// 定义回调函数,用于将下载的数据写入本地文件
size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
    
    
    return fwrite(ptr, size, nmemb, (FILE *)stream);
}

// 子函数,用于下载网络文件到本地
int download_file(const char *url, const char *output_filename) {
    
    
    CURL *curl = curl_easy_init();
    FILE *fp = fopen(output_filename, "wb");  // 打开一个文件用于保存下载的数据

    if (curl && fp) {
    
    
        // 设置下载选项
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);

        // 执行下载请求
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
    
    
            fprintf(stderr, "下载失败: %s\n", curl_easy_strerror(res));
            fclose(fp);
            curl_easy_cleanup(curl);
            return -1;
        }

        fclose(fp);
    } else {
    
    
        fprintf(stderr, "初始化失败\n");
        if (fp) {
    
    
            fclose(fp);
        }
        if (curl) {
    
    
            curl_easy_cleanup(curl);
        }
        return -1;
    }

    curl_easy_cleanup(curl);
    return 0;
}

int main() {
    
    
    const char *url = "http://example.com/file.zip";
    const char *output_filename = "downloaded_file.zip";

    int ret = download_file(url, output_filename);
    if (ret == 0) {
    
    
        printf("文件下载成功!\n");
    } else {
    
    
        printf("文件下载失败!\n");
    }

    return 0;
}

上記のコードでは、download_file関数はネットワーク ファイルをローカルにダウンロードする関数を実装しています。ダウンロードする URL リンクとローカルに保存するファイル パスを関数パラメータとして渡します。この関数は内部で libcurl ライブラリを使用して、ダウンロード オプションの設定、ダウンロード リクエストの実行、ローカル ファイルへのデータの書き込みを行います。

main関数では、download_fileファイルのダウンロードを実現する関数を呼び出すことができます。関数の戻り値を判断することで、ファイルのダウンロードが成功したかどうかを判断できます。

コードをコンパイルして実行する手順は、以前に説明した手順と同じです。download_fileネットワークファイルダウンロード機能を実現する関数を呼び出すことで、その関数を他のコードで簡単に再利用したり、エラー処理や拡張を行うことができます。

おすすめ

転載: blog.csdn.net/xiaolong1126626497/article/details/132145043