C language calls libcurl library to download files to local under Linux

1. Project introduction

The current article introduces how to use the C language to call the libcurl library to implement the network file download function under the Linux (Ubuntu) operating system.

libcurl is an open source cross-platform network transmission library for implementing client functions of various network communication protocols in programming languages ​​such as C and C++. It supports a variety of protocols, including HTTP, HTTPS, FTP, SMTP, POP3, etc., and can easily perform data upload and download operations.

image-20230626101116409

Following are some key features and functions of the libcurl library:

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. Environmental preparation

**libcurl library:** can be installed by running the following command in terminal:

sudo apt-get install libcurl4-openssl-dev

GitHub repository: https://github.com/curl/curl
libcurl official website: https://curl.se/libcurl/

3. Design steps

3.1 Importing header files

In the C code file, you need to introduce curl/curl.hthe header file in order to use the functions and structures provided by the libcurl library.

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

3.2 Initialize libcurl

Before the program starts, the libcurl library needs to be initialized. This can be done by calling curl_global_inita function.

curl_global_init(CURL_GLOBAL_DEFAULT);

3.3 Setting download options

Next, you need to set the download options, including the URL link to download, the file path to save locally, and so on. Options can be curl_easy_setoptset using functions.

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 Executing a download request

Call curl_easy_performthe function to execute the download request and save the file to the specified path. During execution, the libcurl library automatically handles network transfers and receiving file data.

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

3.5 Clean up resources

Finally, at the end of the program, libcurl's resources need to be cleaned up. This can be done by calling curl_easy_cleanupa function.

curl_easy_cleanup(curl);

3.6 Complete sample code

The following is a complete sample code to demonstrate how to use C language and libcurl library to implement network file download function under 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 Compile and run

In a terminal, compile the sample code with the following command:

gcc -o download_program download_program.c -lcurl

Then, execute the downloader by running the resulting executable:

./download_program

4. Complete code

The following is a sub-function that encapsulates the network file download function:

#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;
}

In the above code, download_filethe function implements the function of downloading network files to the local. Pass in the URL link to be downloaded and the file path to save locally as function parameters. The function internally uses the libcurl library to set download options, execute download requests, and write data to local files.

In mainthe function, you can call download_filethe function to realize the file download. By judging the return value of the function, you can judge whether the file download is successful.

The steps to compile and run the code are the same as those presented previously. By calling download_filea function to realize the network file download function, the function can be easily reused in other codes, and error handling and extension can be performed.

Guess you like

Origin blog.csdn.net/xiaolong1126626497/article/details/132145043
Recommended