如何使用curl編程來下載文件

一口Linux 2026-08-02 20:29

libcurl 是一個功能強大的跨平臺網絡傳輸庫,支持多種協議。

圖片

關注“碼農愛學習”,設置“星標公眾號

本篇來介紹libcul的C語言編程,實現一個文件下載的功能。

1 curl基礎介紹

1.1 核心數據結構

1.1.1 CURL句柄

CURL是libcurl 的核心句柄,每個請求對應一個 CURL 實例,是配置請求參數、執行操作的主要載體。

其特性包括:

  • 獨立性:每個句柄都是獨立的,配置互不影響
  • 可復用性:一個句柄在完成一次請求后,可通過重新設置選項再次使用,無需重復創建和銷毀
  • 狀態存儲:句柄內部存儲了請求的所有狀態信息,直到被釋放

1.1.2 CURLcode返回值

CURLcode是函數返回值類型,用于判斷操作是否成功。

成功狀態為:CURLE_OK

所有的返回值枚舉如下:

typedef enum {
  CURLE_OK = 0,                   /* 操作成功 */
  CURLE_UNSUPPORTED_PROTOCOL,     /* 不支持的協議 */
  CURLE_FAILED_INIT,              /* 初始化失敗(如 curl_global_init 調用失敗) */
  CURLE_URL_MALFORMAT,            /* URL 格式錯誤 */
  CURLE_URL_MALFORMAT_USER,       /* URL 中的用戶名/密碼格式錯誤 */
  CURLE_COULDNT_RESOLVE_PROXY,    /* 無法解析代理服務器 */
  CURLE_COULDNT_RESOLVE_HOST,     /* 無法解析主機名(DNS 失敗) */
  CURLE_COULDNT_CONNECT,          /* 無法連接到服務器 */
  CURLE_WEIRD_SERVER_REPLY,       /* 服務器返回異常響應 */
  CURLE_REMOTE_ACCESS_DENIED,     /* 遠程訪問被拒絕(如權限不足) */
  CURLE_FTP_ACCEPT_FAILED,        /* FTP 接受連接失敗 */
  CURLE_FTP_WEIRD_PASS_REPLY,     /* FTP 密碼響應異常 */
  CURLE_FTP_ACCEPT_TIMEOUT,       /* FTP 接受超時 */
  CURLE_FTP_WEIRD_PASV_REPLY,     /* FTP PASV 命令響應異常 */
  CURLE_FTP_WEIRD_227_FORMAT,     /* FTP 227 響應格式錯誤 */
  CURLE_FTP_CANT_GET_HOST,        /* FTP 無法獲取主機信息 */
  CURLE_HTTP2,                    /* HTTP/2 相關錯誤 */
  CURLE_FTP_COULDNT_SET_TYPE,     /* FTP 無法設置傳輸類型(ASCII/BINARY) */
  CURLE_PARTIAL_FILE,             /* 只接收到部分文件(未完成全量下載) */
  CURLE_FTP_COULDNT_RETR_FILE,    /* FTP 無法檢索文件 */
  CURLE_OBSOLETE4,                /* 已廢棄(歷史版本使用) */
  CURLE_QUOTE_ERROR,              /* FTP QUOTE 命令執行失敗 */
  CURLE_HTTP_RETURNED_ERROR,      /* HTTP 服務器返回錯誤狀態碼(如 4xx、5xx) */
  CURLE_WRITE_ERROR,              /* 寫入數據失敗(如本地文件寫入失敗) */
  CURLE_OBSOLETE9,                /* 已廢棄 */
  CURLE_UPLOAD_FAILED,            /* 上傳失敗 */
  CURLE_READ_ERROR,               /* 讀取數據失敗(如本地文件讀取失敗) */
  CURLE_OUT_OF_MEMORY,            /* 內存不足 */
  CURLE_OPERATION_TIMEDOUT,       /* 操作超時 */
  CURLE_OBSOLETE14,               /* 已廢棄 */
  CURLE_FTP_PORT_FAILED,          /* FTP PORT 命令執行失敗 */
  CURLE_FTP_COULDNT_USE_REST,     /* FTP REST 命令不被支持 */
  CURLE_OBSOLETE17,               /* 已廢棄 */
  CURLE_RANGE_ERROR,              /* 范圍請求錯誤(服務器不支持 Range 或范圍無效) */
  CURLE_HTTP_POST_ERROR,          /* HTTP POST 數據傳輸錯誤 */
  CURLE_SSL_CONNECT_ERROR,        /* SSL/TLS 連接失敗 */
  CURLE_BAD_DOWNLOAD_RESUME,      /* 斷點續傳失敗(如文件不存在或偏移量無效) */
  CURLE_FILE_COULDNT_READ_FILE,   /* 無法讀取本地文件 */
  CURLE_LDAP_CANNOT_BIND,         /* LDAP 綁定失敗 */
  CURLE_LDAP_SEARCH_FAILED,       /* LDAP 搜索失敗 */
  CURLE_OBSOLETE24,               /* 已廢棄 */
  CURLE_FUNCTION_NOT_FOUND,       /* 未找到指定的回調函數 */
  CURLE_ABORTED_BY_CALLBACK,      /* 被回調函數中止(如進度回調返回非零值) */
  CURLE_BAD_FUNCTION_ARGUMENT,    /* 回調函數參數錯誤 */
  CURLE_OBSOLETE28,               /* 已廢棄 */
  CURLE_OBSOLETE29,               /* 已廢棄 */
  CURLE_PARTIAL_FILE_FROM_cache,  /* 從緩存獲取到部分文件 */
  CURLE_OBSOLETE31,               /* 已廢棄 */
  CURLE_SSL_ENGINE_NOTFOUND,      /* 未找到 SSL 引擎 */
  CURLE_SSL_ENGINE_SETFAILED,     /* SSL 引擎初始化失敗 */
  CURLE_SEND_ERROR,               /* 發送數據失敗(網絡發送錯誤) */
  CURLE_RECV_ERROR,               /* 接收數據失敗(網絡接收錯誤) */
  CURLE_OBSOLETE36,               /* 已廢棄 */
  CURLE_SSL_CERTPROBLEM,          /* SSL 證書問題(如無效、過期) */
  CURLE_SSL_CIPHER,               /* 無法協商 SSL 加密套件 */
  CURLE_SSL_CACERT,               /* 無法驗證 SSL CA 證書 */
  CURLE_BAD_CONTENT_ENCODING,     /* 內容編碼錯誤(如服務器返回無效的 gzip 數據) */
  CURLE_LDAP_INVALID_URL,         /* LDAP URL 無效 */
  CURLE_FILESIZE_EXCEEDED,        /* 文件大小超出限制 */
  CURLE_USE_SSL_FAILED,           /* 啟用 SSL 失敗 */
  CURLE_SEND_FAIL_REWIND,         /* 發送數據前重繞(rewind)失敗 */
  CURLE_SSL_ENGINE_INITFAILED,    /* SSL 引擎初始化失敗 */
  CURLE_LOGIN_DENIED,             /* 登錄被拒絕(如用戶名/密碼錯誤) */
  CURLE_TFTP_NOTFOUND,            /* TFTP 文件未找到 */
  CURLE_TFTP_PERM,                /* TFTP 權限錯誤 */
  CURLE_REMOTE_DISK_FULL,         /* 遠程磁盤滿 */
  CURLE_TFTP_ILLEGAL,             /* TFTP 非法操作 */
  CURLE_TFTP_UNKNOWNID,           /* TFTP 未知傳輸 ID */
  CURLE_REMOTE_FILE_EXISTS,       /* 遠程文件已存在(不允許覆蓋) */
  CURLE_TFTP_NOSUCHUSER,          /* TFTP 無此用戶 */
  CURLE_CONV_FAILED,              /* 字符編碼轉換失敗 */
  CURLE_CONV_REQD,                /* 需要字符編碼轉換但未啟用 */
  CURLE_SSL_CACERT_BADFILE,       /* SSL CA 證書文件不存在或無法讀取 */
  CURLE_REMOTE_FILE_NOT_FOUND,    /* 遠程文件未找到 */
  CURLE_SSH,                      /* SSH 相關錯誤 */
  CURLE_SSL_SHUTDOWN_FAILED,      /* SSL 關閉失敗 */
  CURLE_AGAIN,                    /* 操作需要重試(非錯誤,用于異步操作) */
  CURLE_SSL_CRL_BADFILE,          /* CRL 文件錯誤 */
  CURLE_SSL_ISSUER_ERROR,         /* SSL  issuer 證書驗證失敗 */
  CURLE_FTP_PRET_FAILED,          /* FTP PRET 命令失敗 */
  CURLE_RTSP_CSEQ_ERROR,          /* RTSP CSEQ 不匹配 */
  CURLE_RTSP_SESSION_ERROR,       /* RTSP 會話錯誤 */
  CURLE_FTP_BAD_FILE_LIST,        /* FTP 文件列表格式錯誤 */
  CURLE_CHUNK_FAILED,             /* HTTP 分塊傳輸編碼錯誤 */
  CURLE_NO_CONNECTION_AVAILABLE,  /* 無可用連接(連接池耗盡) */
  CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* SSL 固定公鑰不匹配 */
  CURLE_SSL_INVALIDCERTSTATUS,    /* SSL 證書狀態無效 */
  CURLE_HTTP2_STREAM,             /* HTTP/2 流錯誤 */
  CURLE_RECURSIVE_API_CALL,       /* 遞歸調用 libcurl API */
  CURLE_AUTH_ERROR,               /* 認證錯誤 */
  CURLE_HTTP3,                    /* HTTP/3 相關錯誤 */
  CURLE_QUIC_CONNECT_ERROR,       /* QUIC 連接錯誤 */
  CURLE_PROXY,                    /* 代理相關錯誤 */
  CURLE_SSL_CLIENTCERT,           /* 客戶端證書錯誤 */
  CURLE_UNRECOVERABLE_POLL,       /* 無法恢復的輪詢錯誤 */
  CURLE_LAST /* 標記枚舉結束(無實際意義) */
} CURLcode;

1.2 初始化與清理

1.2.1 curl_global_init

初始化 libcurl 全局環境,必須在所有其他 libcurl 函數之前調用

CURLcode curl_global_init(long flags);
  • 參數:flags 通常使用 CURL_GLOBAL_DEFAULT(默認初始化)
  • 返回值:CURLcode 類型,成功返回 CURLE_OK

curl_global_init 通常需要手動調用,如果不調用,在第一次調用curl_easy_init時,libcurl 會隱式調用

curl_global_init(CURL_GLOBAL_DEFAULT),但這種行為不可靠,可能存在以下問題:

  • 無法指定初始化選項(只能使用默認配置)
  • 無法捕獲 curl_global_init 的返回值(若初始化失敗,難以排查原因)
  • 可能導致多線程環境下的競爭條件(非線程安全)
  • 部分平臺或 libcurl 編譯選項可能禁用此功能

如果代碼邏輯較簡單,或剛開始學習curl,簡化邏輯可先只調用curl_easy_init。

1.2.2  curl_easy_init

創建一個 CURL 句柄,用于配置單次請求

CURL *curl_easy_init(void);
  • 返回值:成功返回 CURL* 句柄,失敗返回 NULL

1.2.3 curl_easy_cleanup

釋放 CURL 句柄資源

void curl_easy_cleanup(CURL *curl);

1.2.4 curl_global_cleanup

清理 libcurl 全局環境,程序結束前調用

void curl_global_cleanup(void);

1.3 下載核心配置 API

1.3.1 curl_easy_setopt

設置 CURL 句柄的各種選項(核心函數,幾乎所有配置都通過它完成)

函數原型:

CURLcode curl_easy_setopt(CURL *curl, CURLoption option, parameter);

參數:

  • CURL *curl:指向 CURL 句柄的指針,由 curl_easy_init() 創建,用于標識一個 curl 會話

  • CURLoption option:枚舉類型的選項參數,指定要設置的具體配置(如 URL、超時時間、回調函數等),例如:

    • CURLOPT_URL(設置請求的 URL)
    • CURLOPT_WRITEFUNCTION(設置數據接收回調函數)
  • parameter:選項對應的參數值,類型根據option不同而變化:

    • 可能是字符串(如 URL 地址)、整數(如超時時間)、函數指針(如回調函數)等。
    • 若選項不需要參數,此值可設為 0 或 NULL(根據具體選項要求)

1.3.2 與文件下載相關的一些選項

  • CURLOPT_URL:設置下載的 URL(必填)

    示例:curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.zip");

  • CURLOPT_WRITEFUNCTION:設置回調函數,用于處理下載的文件數據

    回調函數原型:

    size_t (*curl_write_callback)(void *ptr, size_t size, size_t nmemb, void *userp);
    • ptr:下載到的數據緩沖區;
    • size:每個數據塊的大小;
    • nmemb:數據塊數量;
    • userp:自定義參數(通常是文件指針等);
    • 返回值:實際處理的字節數(需返回 size * nmemb,否則可能中斷下載)。
  • CURLOPT_WRITEDATA:設置傳遞給 CURLOPT_WRITEFUNCTION 回調的自定義參數(如文件指針)

    示例:curl_easy_setopt(curl, CURLOPT_WRITEDATA, file_ptr);

  • CURLOPT_FOLLOWLOCATION:設置為 1L 時,自動跟隨 HTTP 重定向(如 301/302)

  • CURLOPT_SSL_VERIFYPEER:設置為 0L 時,忽略 SSL 證書驗證(僅測試用,生產環境不推薦)

  • CURLOPT_PROGRESSFUNCTION:設置進度回調函數,用于跟蹤下載進度。

    回調原型:

    int (*progress_callback)(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
    • dltotal:總下載大小
    • dlnow:已下載大小
  • CURLOPT_NOPROGRESS:設置為 0L 時,啟用進度回調(需配合 CURLOPT_PROGRESSFUNCTION 使用)

1.4 執行下載與獲取信息

1.4.1 curl_easy_perform

執行配置好的請求(開始數據傳輸)

CURLcode curl_easy_perform(CURL *curl);
  • 參數:指向已配置好的 CURL 句柄的指針
  • 返回值:CURLcode 類型,CURLE_OK 表示下載成功

1.4.2 curl_easy_getinfo

獲取下載相關信息(需在 curl_easy_perform 執行后調用)

CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);

參數:

  • CURL *curl:指向已執行過請求的 CURL 句柄的指針
  • CURLINFO info:枚舉類型的參數,指定要獲取的信息類型,例如:
    • CURLINFO_RESPONSE_CODE(HTTP 響應碼)
    • CURLINFO_SIZE_DOWNLOAD(下載總字節數)
  • ...:可變參數,指向用于存儲結果的變量指針,類型根據 info 不同而變化(如整數指針、雙精度指針、字符串指針等)

2 文件下載基礎示例

2.1 curl下載主邏輯

主要調用的接口如下:

  • curl_easy_init:初始化curl句柄
  • curl_easy_setopt:設置選項(文件下載地址,下載的回調函數)
  • curl_easy_perform:執行文件下載
void http_file_download(const char *url, const char *name)
{
    printf("[%s] in\n", __func__);
    
    int fd = open(name, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
    if (-1 == fd)
    {
        printf("[%s] create file:%s failed\n", __func__, name);
        return;
    }
    printf("[%s] create file:%s ok\n", __func__, name);
        
    printf("[%s] curl init\n", __func__);
    CURL *curl = curl_easy_init();
    
    printf("[%s] curl setopt, url:%s\n", __func__, url);
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file_cb); 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fd); 
    
    printf("[%s] curl performt\n", __func__);
    curl_easy_perform(curl);
    
    printf("[%s] close file\n", __func__);
    close(fd);
    
    printf("[%s] out\n", __func__);   
}

2.2 下載數據的回調

下載數據的回調,需要根據回調函數的原型,自己實現具體的內容,這里就是將接收的數據通過write方法寫入自己創建的文件。

文件的創建是在上面的http_file_download中通過open方法創建一個文件,并通過curl_easy_setopt的CURLOPT_WRITEDATA選項將文件

的fd句柄傳給回調函數。

size_t write_file_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    static int i = 0;
    size_t this_size = size * nmemb;
    printf("[%s] <%d> total size:%zu\n", __func__, ++i, this_size);
    
    int fd = *((int *)userdata);
    write(fd, ptr, this_size);
    
    return this_size;
}

2.3 主函數

要測試文件下載,需要先找一個文件下載連接,可以先通過瀏覽器下載一個文件,然后在下載記錄中,復制其下載鏈接:

文件下載的測試主函數中,就是調用上面的curl函數接口,傳入下載鏈接:

// gcc download_file.c -o download_file -l curl
#include <stdio.h>
#include <curl/curl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>

constchar *file_url = "https://vscode.download.prss.microsoft.com/dbazure/download/stable/488a1f239235055e34e673291fb8d8c810886f81/code_1.102.3-1753759567_amd64.deb";
constchar *file_name = "my_download.deb";

int main()
{
    printf("hello\n");
    
    time_t start;
    time_t end;
    
    time(&start);
    http_file_download(file_url, file_name);
    time(&end);
    
    int esapsed = difftime(end, start);
    printf("esapsed time:%d sec\n", esapsed);
    
    return0;
}

運行結果下:

通過linux系統自帶的md5sum功能,對比通過瀏覽器下載的文件,和通過curl編寫的程序下載的文件,MD5的值是一樣的,說明下載的文件是對的。

3 多線程下載

curl下載文件,主要時間是在執行curl_easy_perform時阻塞,直到文件下載完成。

使用多線程下載的基本思路,就是創建多個curl句柄,對要下載的文件進行分段下載,在多個線程中,各自執行curl_easy_perform,來下載文件的各個部分的數據。

3.1 curl下載主邏輯

在下載主邏輯中,使用多線程的下載,與剛才單線程的主要區別是:

  • 需要先知道要下載的文件長度,便于進行分段下載的任務分配,這個通過編寫一個get_download_length來實現
  • 根據文件大小,提前為文件開辟空間,用來進行分段寫入,這個通過lseek方法來實現
  • 將文件映射到虛擬內存,這個通過mmap方法來實現
  • 創建多個線程,在每個線程中,執行各自數據的下載,創建線程可通過pthread_create方式
void http_file_download(const char *url, const char *name)
{
    printf("[%s] in\n", __func__);
    
    //要下載的文件長度
    longlong file_length = get_download_length(url);
    if (-1 == file_length)
    {
        return;
    }
    printf("[%s] file_length:%lld\n", __func__, file_length);
    
    //創建一個文件
    int fd = open(name, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
    if (-1 == fd)
    {
        printf("[%s] create file:%s failed\n", __func__, name);
        return;
    }
    printf("[%s] create file:%s ok\n", __func__, name);
    
    //先給文件開辟一塊空間
    if (-1 == lseek(fd, file_length -1, SEEK_SET))
    {
        printf("[%s] lseek failed\n", __func__);
        goto DONE;
    }
    
    if (1 != write(fd, "\0"1))
    {
        printf("[%s] write failed\n", __func__);
        goto DONE;
    }
    
    //將文件映射到虛擬內存
    void *fileptr = mmap(NULL, file_length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (MAP_FAILED == fileptr)
    {
        printf("[%s] mmap failed\n", __func__);
        goto DONE;
    }
    
    //創建線程
    pthread_t threads[MULTI_DOWNLOAD_THEAD_NUM];
    //ThreadParam threadParam[MULTI_DOWNLOAD_THEAD_NUM];
    for (int i = 0; i < MULTI_DOWNLOAD_THEAD_NUM; i++)
    {
        threadParam[i].thrd_num = (i+1);
        threadParam[i].url = (char *)url;
        threadParam[i].range[0] = (file_length / MULTI_DOWNLOAD_THEAD_NUM) * i;
        threadParam[i].range[1] = (MULTI_DOWNLOAD_THEAD_NUM - 1 == i) ? (file_length - 1) : (file_length / MULTI_DOWNLOAD_THEAD_NUM) * (i + 1) - 1
        threadParam[i].ptr = fileptr + threadParam[i].range[0];
        threadParam[i].offset = 0;
        pthread_create(&threads[i], NULL, thread_func, &threadParam[i]);
    }
    
    for (int i = 0; i < MULTI_DOWNLOAD_THEAD_NUM; i++)
    {
        pthread_join(threads[i], NULL);
    }
    printf("[%s] all download done\n", __func__);
    
    munmap(fileptr, file_length);
    
DONE:
    printf("[%s] close file\n", __func__);
    close(fd);
    
    printf("[%s] out\n", __func__);   
}

3.1.1 mmap的介紹

mmap 是 Unix/Linux 系統中用于將文件或設備映射到進程虛擬內存空間的系統調用,其函數原型如下:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

參數:

  • void *addr:期望的映射起始地址(通常設為 NULL,由操作系統自動選擇合適的地址)

  • size_t length:要映射的字節數(必須大于 0),通常是文件的大小

  • int prot:映射區域的保護權限(內存訪問權限),可組合以下值:

    • PROT_READ:可讀(必須有,否則無法訪問映射區域)
    • PROT_WRITE:可寫(修改映射區域會同步到文件)
    • PROT_EXEC:可執行(映射區域的內容可作為代碼運行)
    • PROT_NONE:不可訪問(無任何權限)
  • int flags:映射類型和屬性,關鍵取值(必選其一):

    • MAP_ANONYMOUS:匿名映射(無關聯文件,用于進程間共享內存),此時 fd 需設為 -1
    • MAP_FIXED:強制使用 addr 作為起始地址(若無法映射會失敗,不推薦隨意使用)
    • MAP_SHARED:共享映射。修改映射區域會同步到文件,且對其他映射該文件的進程可見

    • MAP_PRIVATE:私有映射。修改映射區域不會同步到文件,僅創建進程可見(寫時復制)

    • 其他常用標志:

  • int fd:要映射的文件描述符(通過 open 打開的文件句柄)

  • off_t offset:從文件的哪個偏移量開始映射(必須是系統頁大小的整數倍,通常為 4KB 或 8KB)

返回值:

  • 成功:返回映射區域的起始地址(void* 指針)
  • 失敗:返回 MAP_FAILED(通常是 (void*)-1),并設置 errno 指示錯誤原因,例如:
    • EBADF 表示文件描述符無效
    • EACCES 表示權限不足

3.1.2 關于數據分段的計算

假設數據的長度為file_length,有N個線程進行同時下載,則將數據平均分為N份(0、1、...、N-1),由于可能無法正好平均分,則最后一份剩余多少就是多少。

3.2 獲取文件的長度

獲取文件長度的原理,也是通過curl來執行一次數據傳輸,只不過,不是獲取數據本身,只是獲取數據頭數據,然后通過curl_easy_getinfo來獲取數據頭中包含的數據長度信息。

long long get_download_length(const char *url)
{   
    CURL *curl = curl_easy_init();
    
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"); //opt(about://version)
    curl_easy_setopt(curl, CURLOPT_HEADER, 1); //opt
    curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
        
    if (CURLM_OK != curl_easy_perform(curl))
    {
        printf("[%s] failed\n", __func__);
        return-1;
    }
    
    double res = 0//double類型
    curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &res);
    download_len = (longlong )res;
    
    return download_len;
}

3.3 線程函數

線程函數的內容,其實就是在單線程下載的示例程序中的那些curl的接口調用邏輯。

主要調用的接口如下:

  • curl_easy_init:初始化curl句柄
  • curl_easy_setopt:設置選項(文件下載地址,下載的回調函數)
  • curl_easy_perform:執行文件下載
void *thread_func(void *arg)
{
    ThreadParam *par = (ThreadParam *)arg;
    char range[64] = {0};
    sprintf(range, "%lld-%lld", par->range[0], par->range[1]);
    
    //創建一個curl對象 
    printf("[%s] thrd<%d> curl init\n", __func__, par->thrd_num);
    CURL *curl = curl_easy_init();
    
    printf("[%s] thrd<%d> curl setopt, url:%s, range:%s\n", __func__, par->thrd_num, par->url, range);
    curl_easy_setopt(curl, CURLOPT_URL, par->url);
    curl_easy_setopt(curl, CURLOPT_RANGE, range);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file_cb); 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, par); 
    
    curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); 
    curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, download_progress_cb); 
    curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, par); 
    
    //執行網絡請求
    printf("[%s] thrd<%d> curl performt\n", __func__, par->thrd_num);
    CURLcode res = curl_easy_perform(curl);   
    if (CURLE_OK != res)
    {
        printf("[%s] thrd<%d> curl_easy_perform err:%d\n", __func__, par->thrd_num, res);
    }
    printf("[%s] thrd<%d> curl performt done\n", __func__, par->thrd_num);
}

這里curl_easy_setopt新增了對下載數據進度的回調邏輯,可以在下載文件的過程中,顯示下載的進度

3.4 下載數據的回調

下載數據的回調,需要根據回調函數的原型,自己實現具體的內容,這里就是將接收的數據通過memcpy方法寫入自己創建的文件。

size_t write_file_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
{
    static int i = 0;
    size_t this_size = size * nmemb;
    //printf("[%s] <%d> total size:%zu\n", __func__, ++i, this_size);
    
    ThreadParam *par = (ThreadParam *)userdata;
    memcpy(par->ptr + par->offset, ptr, this_size);
    par->offset += this_size;
    
    return this_size;
}

3.5 文件下載進度

下載進度的回調,需要根據回調函數的原型,自己實現具體的內容。

int download_progress_cb(void *userdata, double totalDownload, double nowDownload, double totalUpload, double nowUpload)
{
    ThreadParam *par = (ThreadParam *)userdata;
    par->download = nowDownload;

    int percent = 0;
    staticint lastPercent = -1;
    if (totalDownload > 0)
    {
        double allDownload = 0;
        for (int i = 0 ;i < MULTI_DOWNLOAD_THEAD_NUM; i++)
        {
            allDownload += threadParam[i].download;
        }
    
        percent = (int)(allDownload / download_len * 100);
    }
    
    if (lastPercent != percent)
    {
        lastPercent = percent;
        printf("[%s] percent:%d%%\n", __func__, percent);
    }
    
    return0;
}

3.6 主函數

主函數的內容如下:

// gcc download_file_multi_thread.c -o download_file_multi_thread -lcurl -lpthread

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>


constchar *file_url = "https://vscode.download.prss.microsoft.com/dbazure/download/stable/488a1f239235055e34e673291fb8d8c810886f81/code_1.102.3-1753759567_amd64.deb";
constchar *file_name = "my_multithread_download.deb";

#define MULTI_DOWNLOAD_THEAD_NUM (3)

typedefstruct
{

    int thrd_num;
    char *url;
    longlong range[2];
    char *ptr;
    int offset;
    double download;
}ThreadParam;

ThreadParam threadParam[MULTI_DOWNLOAD_THEAD_NUM];

longlong download_len = -1;

size_t write_file_cb(char *ptr, size_t size, size_t nmemb, void *userdata);
int download_progress_cb(void *userdata, double totalDownload, double nowDownload, double totalUpload, double nowUpload);
long long get_download_length(const char *url);
void *thread_func(void *arg);
void http_file_download(const char *url, const char *name);

int main()
{
    printf("hello\n");
    
    time_t start;
    time_t end;
    
    time(&start);
    http_file_download(file_url, file_name);
    time(&end);
    
    int esapsed = difftime(end, start);
    printf("esapsed time:%d sec\n", esapsed);
    
    return0;
}

運行結果如下:

可以看到,3個線程的下載依次完成,進度最終顯示到100%,文件下載完成。

不過,通過計時打印,多個線程下載,總耗時卻沒有減少,有待再研究。

4 總結

本篇介紹了如何使用curl編程實現文件的下載,首先介紹了curl編程的一些基礎API的使用,然后通過實例編程,來實現一個文件下載的功能。

一口Linux 寫點代碼,寫點人生!
評論
  • 行業痛點凸顯,飛凌嵌入式FET3572-C重磅登場工業4.0與AIoT發展下,嵌入式核心板作為設備“工業大腦”,面臨性能與功耗的雙重考驗——既要支撐復雜算法和多路數據處理,又要兼顧便攜設備、工業終端的低功耗需求,傳統核心板“高性能必高功耗”的困境制約設備升級。為此,飛凌嵌入式推出基于RK3572處理器的FET3572-C核心板,以2×Cortex-A73+6×Cortex-A53八核架構為核心,實現“性能翻倍、功耗減半”的突破,為中高端嵌入式場景提供優質算力底座。八核異構架構,解鎖性能功耗最優解
    飛凌嵌入式 2026-07-31 09:47 170瀏覽
  •     長期專注WiFi領域,也算是行業老兵了!同行閑聊中,時不時能提起我和我們!從疫情起,國產替代風生水起,起起落落,大浪淘沙,生存下來的都是強者!    WiFi模塊應用廣泛,對于高端市場和特定市場,要求WIFI模塊需要過CE/FCC之類的認證,也就是說沒有認證的模塊,不具備導入產品設計.接下來就和大家聊聊認證模塊選型參考!    WIFi模塊硬件方面主要考慮以下九點特性:    1
    納拓科技 2026-07-31 17:56 128瀏覽
  • 摘要在防爆電氣設計中,只參照芯數選型而忽略額定載流量,長期滿負荷運行會出現插頭發熱、接觸面氧化、IP67 密封受熱老化等問題。結合常用 3 針 3 孔、4 芯、5PIN、8PIN 圓形防爆連接器,制作分級電流參數對照表,區分冷壓免焊接、焊接兩種接線結構的安全載流數值,設置合理電流冗余系數,搭配使用環境修正參數,規范防爆接近開關連接器、防爆法蘭插座的選型計算方式。關鍵詞圓形防爆連接器,載流參數表,防爆法蘭插座,防爆端子接頭,IP67 防爆防水接插件1 產品概述圓形防爆連接器觸點載流能力由插針直徑、
    用戶1783664076620 2026-08-03 09:18 72352瀏覽
  • 摘要防爆自控系統同時布設本安信號、工業總線、動力供電三類線路,僅依靠標識標牌管控插接極易出現人為錯插問題,高壓動力回路竄入本安弱電回路會突破安全柵限能標準,產生點火風險。依托 A、D、K 標準化機械防呆編碼體系,搭配護套顏色區分管理,適配 3 針 3 孔免焊接冷壓增安型防爆航插、5PIN 總線防爆航空插頭、8 芯焊接防爆法蘭插座的選型使用,從物理結構層面杜絕防爆接近開關連接器、防爆傳感器航插接頭混用插接問題,補齊防爆系統被動安全防護體系。關鍵詞圓形防爆連接器,防呆編碼防爆航插,防爆航空插頭,防爆
    用戶1783664076620 2026-07-31 18:29 255瀏覽
  • 在EMC測試過程中,傳導發射(Conducted Emission,CE)超標是工程師最常遇到的問題之一。更令人頭疼的是,同樣的超標曲線背后,可能對應著完全不同的干擾機理:有的是差模噪聲沿電源回路傳播,有的是共模電流通過寄生路徑耦合,還有些問題甚至并非來自電源本身,而是負載、電纜布局或接地結構引起的連鎖反應。 · 150kHz~1MHz 超標:多為差模噪聲為主,干擾沿火線-零線回路傳輸。 · 1MHz~30MHz 超標:通常共模噪聲占主導,干擾通過火線/零線對地回路傳播。 如果條件允許,用電流探
    譽磁電磁兼容EMC 2026-07-31 18:45 272瀏覽
  • 在芯片總成本中占比不到 1%,卻可能因一處品質偏差導致整片晶圓報廢——半導體切割/研磨膠帶,正隨著先進封裝的爆發,成為封測產線選型中最謹慎對待的耗材之一。但鮮有人注意到,決定這層膠帶性能上限的,是上游一層更薄的基膜。這個長期由日本企業主導的隱形環節,正在出現國產突圍的信號。一、需求之變:先進封裝與“韜定律”重塑膠帶市場AI 算力芯片、HBM 高帶寬存儲、Chiplet 芯粒等先進封裝產品持續放量,國內封測產線擴產節奏不減。作為晶圓減薄與切割工序的必需耗材,晶圓膠帶的需求同步擴容。據 QYRese
    芯膜前沿 2026-07-31 16:35 261瀏覽
  • Synopsys 這次沒有再給行業看一條只能站在展臺邊圍觀的 demo。7 月 27 日,Synopsys 在 DAC 2026 期間公布兩條 autonomous EDA workflow:一條處理 debug closure,另一條處理 implementation and closure。客戶可以通過 Synopsys 申請在 Microsoft Discovery 上評估,AMD 正在評估這些工作流能否用于下一代產品開發。公告里最扎眼的是 25%–40%。Synopsys 稱
    麒芯說AI 2026-07-31 14:21 160瀏覽
  • 光芯片,正在從光模塊的“配角”逆襲為AI產業鏈的“命門”2026年3月,英偉達一紙公告震動整個光通信行業——分別向Lumentum和Coherent各投資20億美元,合計40億美元。這哪是什么財務投資,這是一次對AI基礎設施關鍵環節的“掐尖式”卡位。光芯片,這個曾經被市場當作光模塊BOM表里一個標準配套元器件的東西,正在成為AI產業鏈上“卡位”最強、話語權最硬的環節。一、為什么是光芯片?老黃早就把話挑明了英偉達CEO黃仁勛的原話是:數據傳輸速度已成為人工智能發展的新瓶頸。AI集群從萬卡級往十萬卡
    用戶1774416745629 2026-07-31 11:22 268瀏覽
  •         很多人拆解醫療設備時,只會關注傳感器、主控芯片這類核心部件,卻忽略了電路板上不起眼的晶振。作為整個醫療系統的時間基準,晶振的精度、穩定性直接決定了測量數據的準確性、設備的運行安全性——比如監護儀的采樣頻率偏了1ppm,血氧、心率的讀數就會出現系統性偏差;膠囊內窺鏡的時鐘漂移超標,圖像傳輸就會出現丟包、花屏。不同醫療場景對晶振的要求天差地別,沒有一款晶振能通吃所有設備,每一類醫療設備背后,都有一套針對性的晶振選型邏輯。1. 家用便攜監測設備:
    TKD泰晶科技 2026-07-31 08:24 471瀏覽
  • 智能寵物用品這幾年快速普及,自動清理幾乎成了智能貓砂盆的標配。貓咪用完離場,設備自動翻轉清理,養寵家庭省去了每天彎腰清理的麻煩。但自動清理的第一步,是先準確判斷貓到底在不在盆里。這個看似簡單的問題,在小空間里并不容易做好。近場檢測的痛點:距離太遠反而誤事貓砂盆內部空間有限。如果傳感器的檢測距離設得偏大,盆外路過的貓、人甚至物品都會被誤判為貓在盆內,結果該清理時不清理、不該清理時亂清理,體驗直接崩壞。這類產品的核心訴求其實就一句話:近距離、小范圍、精準識別,不能有半點誤判。常規感應方案常因檢測距離
    唯創知音語音芯片 2026-07-31 16:51 212瀏覽
  • ?摘要:低價大流量卡正全面退市,政策收緊已成定局。面對傳統號卡的不確定性,隨身WiFi憑借穩定連接、多設備共享、獨立設備和靈活套餐等優勢,成為務實可靠的備選方案。1、流量卡黃金時代要結束了通信行業正迎來一場前所未有的“地震式”調整——曾讓無數用戶追捧的低價大流量卡,正在全速退出各大平臺。這早已不是一次普通的競合,而是一場趨勢性的行業洗牌。回望過去,19元200G的神卡,那時真是“睡著都能笑醒”,便宜到不敢相信,爽到忍不住炫耀。那些日子,好像隨便刷、隨便看,流量自由觸手可及。可如今,回頭再看,那種
    愛上電路設計 2026-08-03 10:21 72550瀏覽
  • 今年好幾個客戶都問過我同一件事。藍牙音頻產品到底用 WT2605 這種單芯片,還是老老實實 MCU 外掛藍牙模組。兩種方案我都落地過,說點實在的,WT2605 剛出來那陣我也犯嘀咕,怕是營銷噱頭,真拿來做完一版樣機才服氣。一、選型先看三個維度外圍數量。這是最直觀的。傳統做法是 MCU 加藍牙模組,再加音頻編解碼、功放、晶振和一堆阻容,板子上密密麻麻十幾二十顆料。WT2605 把藍牙、解碼、功放全收進一顆,外圍就剩少量被動件。開發周期。傳統方案得自己接藍牙協議棧,配網、A2DP 解碼、音頻通路一一
    唯創知音語音芯片 2026-07-31 16:35 305瀏覽
我要評論
0
點擊右上角,分享到朋友圈 我知道啦
請使用瀏覽器分享功能 我知道啦
主站蜘蛛池模板: 坏姐姐之拆婚联盟| 福星高照电影| 菲梦少女第二季免费| 旅行到宇宙边缘| 舞蹈家苏科老师简介| 《俘虏之锁》第一集免费| 终极对决电影| 法国空姐八部曲系列| 神犬奇兵电视剧| 韩国产理伦片在线观看| 电影《牙医姐妹》1986版在线| 电影玩火在线观看完整版| 爹地是星际霸主:星际萌宝短剧全集| 大河小虾| 高清《香港奇案之吸血贵利王》电影| 牙医姐妹郝板栗完整版电影| 日本艺妓| 斗罗大陆动漫在线观看免费| 售楼女王在线观看| 变形金刚7| 曲剧包公赔情| 麦乐迪版女超人未删减版| 《伊藤润二惊选集·富江》| 花芯在线观看| 变形记 少年何愁| 欢迎来到实力至上第二季樱花动漫| 《Overflower》动漫全集免费观看第| 汤摇庄的幽奈| 全网影视大全| 《和部长一起去出差旅》韩剧| 女人天下电视剧| 笨贼妙探国语| 双人精油按摩调情刺激阴茎高潮伦理免费电影 | 次子(打一字)| 电影需要爸爸接种子免费观看 | 高清《四大元素之水之魅影》电视剧 | 梦寻桃花源免费观看| 春雨电影大全免费观看在线| 人猿泰山无删减版1995| 真人cs装备厂家| 田纳西ARI和JAY| 年少轻狂| 妈妈职业2的在线观看平台| 天生爱情狂国语| 高压监狱在线观看完整免费高清原声满天星2019法国 | 年少轻狂| 阴阳镇怪谈电影在线观看完整版| 美容院特殊待遇5中文字幕剧情介绍 | 永不消失的番号| 渔夫荒淫史电影在线观看| 时光代理人第四集| 镇魂电视剧在线观看完整版免费| 世间始终你好完整版原唱| 韩剧浪漫满屋中文版| 需要爸爸的种子在线播放| 韩国8层建筑起火| 勇者传说粤语| 日本《乳房按摩》在线| 我知道你爱我| 画皮之阴阳法王完整版免费观看| 年轻的小婊一级A片免费| 人生路不熟电影免费观看完整版| 大凉山姑娘开放| 电影《粉红大白菜》完整版| 撞邪先生| 诱人的岳母| 爆操老妈46集| 云之羽免费观看全集电视剧| 一屋老友记 国语| 妻子和上司出差住酒店怎么办| 惊变无删减| 《永不独眠》在线观看| 陈宝莲满天星绝版免费观看| 仙逆第122集在线观看| 太平轮在线观看| 美国版武则天惊艳版演员表| 电视剧《仁心俱乐部》完整版 | 《潜渊》全集免费播放| 家属6| 女朋友的母亲3中语字追剧易| 冰川时代6| 哇嘎嘎电影高清免费看| 海天雄鹰免费观看| 财阀家的小儿子第七集| 菠萝蜜菠萝蜜影视在线观看 | 玉女心经3:阴阳和合陈慧琳| 97ai蜜桃123| 电影保镖在线观看| 法国伦理电影女子护卫队在线观看 | 《侄女的开发日记》动漫免费观看 | 迷人的保姆高清| 公之浮手中字60| 犬神与七位伙伴| 上瘾12集| 电视剧秋蝉全集免费播放| 西充县| 陈梦说就是要赢给所有人看| 韩国电影丈夫是小帅,丈夫领导是梅川 | 第二次也很美电视剧| 黑色的眼泪完整版| 嘻哈四重奏 第五季| 牙医姊妹电影未删减在线观看网站| 盛夏假期遇见爱全集观看| 法国护士长免费在线观看| 郎咸平说mp3| 摩登原始人满天星版在线叫什么名字| 小越勇辉| 特殊美容院2| 鹰隼大队电视剧| v酒店在线观看| 璀璨人生 电视剧| 野外强伦轩女教师HD| 班杰明现状| 安徽卫视回放| 鹿鼎记在线观看| 想你爱你更恨你美国版| 向爸爸播种电影的英文| 棋王梁家辉| 公与三个媳HD电影| 大运会运动员踏着蜀锦入场| 电影美乃雀主演替夫还债| 放牛班的春天免费| 水手服饲养1小时40分钟视频| 正义雇佣兵| 后进紧身牛仔裤翘臀美女视频| 电视剧骄阳伴我免费观看全集| 兄妹在客厅当父母2上映时间| 爱情有点蓝之爱的交响乐全集| 壤塘县| 二十不惑2电视剧免费播放完整版| 微笑百事达电视剧| 荣昌县| 丈母娘来了电视剧| 萧红电影高清免费观看| 婚姻时差电视剧全集免费观看| 女刑警满天星电影免费观看| 八九不离十| 麦乐迪女超人在线观看完整免费高清 | 二战黑豹电影免费观看高清完整版| 杜拉拉之似水年华结局| 老包青天| 魔力宝贝监狱 电影| 年轻的小姨子2中文| 替身父亲短剧全集免费观看| 请用你的手打扰我| 伦理厨房的岳 BD神马在线观看| 末代皇帝| 《沟壑难填》意大利| 快把我哥带走| 媒体:高铁之大理应放得下卫生巾 | 白日梦我在线观看免费全集| 激战丛林h| 再见龙生你好人生| 张警官免费完整版在线观看| 柳岩热舞| 美容室.特除服务2| 《法国少女农场》在线电影| 史密斯行动国语| 女销售的销售秘诀2免费观看| 盲井无删减完整版| 《倔强退魔师》1-4集免费观看视频 | 年轻的母亲5完整版免费| 变形金刚1迅雷下载| 《爱你几何》完整版| 情牵百子柜| 日韩剧,维修工艳遇| 幸得相遇离婚时短剧免费观看| 罗丽星克莱尔性迷宫片长| 我们都要好好的| 《饥渴的女人和维修工| 整蛊王国语版在线观看| 女子特工满天星| 电视剧棋士免费观看全集| 前辈让我们尽情的相爱吧第一集| 你真漂亮韩剧全集| 妈妈的职业2完整版结局在线看免费| 戈壁母亲| 向往的生活第5季| 向井蓝之特殊治疗医护最新消息 | 无心法师3在线观看免费完整版| 独刺全集免费播放| 暗黑第一季| 国民老公带回家免费观看全集| 神鬼战士1满星版| 教室那一间| 《美国式禁忌2》在线观看| 酋长的女儿电影完整版在线播放| 挤痘大师| 藏海传电视剧免费观看完整版高清| 家庭矛盾4麦乐迪在线观看| 谈股论金股市聊聊吧| 超能机器女友| 法国空乘4免费完整版在线播放 | 老公不在家上司韩国电影| 破产姐妹 第三季| 我的女儿是花| 由菱开始电影免费| 风萧萧兮欲雨| 聊斋艳谭之月光宝盒| 《刑事侦缉档案2》电视剧| 人民海军74周岁| 薰衣草免费高清在线观看大全| 拆弹专家2免费观看完整版| 第一次做aj电视剧| 温柔的背后全集在线观看 | H版《激战丛林》中文完整版| 降魔天师| 海天雄鹰电视剧在线播放| 晚安为我而安眠的妹妹完整版在线观看 | 孽欲狐鬼| 金莲外传2免费全集| 《千金》在线完整观看日剧| 石纪元 第四季 Part 3| 需要爸爸种子 - 在线追剧| 重庆娱乐频道直播| 还珠格格第一部1一24集| 旧里番内衣办公室无删减观看 | 爬山虎的资料| 钻石王牌| 急情从林| 不可剥夺| 最终幻想15王者之剑| 三年大片免费观看国语完| 女体解剖授业| 奇门遁甲国语版| 女特警电视剧免费观看| 十九岁中国高清免费版爱奇艺| 海天雄鹰免费观看| 法证先锋4国语版免费下载| 韩国电影维修工的艳遇| 《敢死队2》| 迪迦奥特曼免费观看| 随唐英雄第四部| 浪漫女家教主演:黛比地区:台湾 | 知几未来| 一片冰心在玉壶电视剧| 金瓶梅2爱的奴隶在线观看| 剩男相亲记| 九一麻花传剧mv在线看看第一集| 死亡之花| 《伯爵夫人和园丁》在线观看免费| 渴望城市电视剧全集| 人世间49集电视剧全集免费观看| 我知道你爱我| 731部队电影完整版 | 旖旎婚色短剧大结局免费观看全集| 没想到儿子的竟然那么大 | 武林外传电视剧| 国风按摩院1-5季顺序| 两个人日本高清| DTF圣路易日记电视剧| 罚罪电视剧免费观看全集在线播放| 美国电影《小辣椒》高清全集 | 意大利《女子护卫队》在线播放免费| 结衣波多野下载| 菲律宾电影楼上楼下| 大象的眼泪 电影| 激战丛林在线观看完整版下载| 美丽的小蜜桃9| 致命黑兰在线观看| 酒店1—20集全集免费高清| 夏天全集在线观看免费| tobu4美国| 梦幻超人动画片| 重庆谍战电视剧全集免费观看 | 我爱吃泡面| 50岁阿姨大人免费观看电视剧全集| 佐佐木明希黑人经典作品推荐| 情深深雨蒙蒙免费观看完整版高清| 罗丽星克莱尔电影在线观看免费 | 迷人的保姆| 刚结婚陪部长出差的日子在线观看 | 买年货小品| 错点鸳鸯电视剧50集免费播放 | 情非情 电视剧| 罗刹海市刀郎原唱完整版| 长月烬明免费观看电视剧高清| 不可磨灭的番号| 双女任务法版| 交个朋友的直播间| 二十一世纪性格爱情指南第8集| 赌博启示录 电影| 无颜之月全集动漫免费观看完整版| 强奸上门女教师在线视频| 电影《顶级特工》| 白色城堡电视剧免费观看| 日本游客在圆明园拍照被网红制止| 帕丁顿熊3电影国语版免费观看| 坎贝奇三级片《无憾》完整版| 高清夜班经理 第二季未删减| 相爱十年 电视剧| 周弘电影在线观看免费| 男朋友弄湿我还问我哪里难受| 《私人航空》免费观看在线观看| 真还传还了8.24亿| 白鹿原全集免费播放| 需要爸爸播种手机播放美国电影免费| 超人变身| 文豪野犬第季第三季| 《需要爸爸播种子》电影免费在线观看,高清完整版美国倫理片_屠夫电影网 | 女保险推销员5中字| 蔷薇风暴1-40集全免费观看| 大侦探福尔摩斯电影| 双女任务无删减版| 假面骑士decade主题曲| 浮之手3| 电影平果| 大秦帝国之裂变电视剧| 全境封锁电影完整| 青面修罗免费观看| 《善良的妻子| 任达华电影全集国语| 女超人无删减版| 《火花》电影| 《德国女子护卫队:满天星》在线观看| 后宫甄嬛传3| 做aj的免费视频大全电视剧免费| 我们的秘密| 宣城市| 动漫无双| 大侦探第8季在线观看免费版高清| 莫妮卡《爱我几何》电影免费无删减 | 粉红女郎高清| 尸城在线| 天地英豪第二部| 敢死队1电影| 日本两个妈妈ID是哪个国家的| 甄嬛传第57集| 夏家三千金第三部| 《庆余年2》第86集| 大神同学想吃掉我| 八戒8| 法医秦明第一季| 娄艺潇新恋情曝光| 漂亮的小瘦子4| 夏至未至豆瓣| 美国版5娃娃脸| 碟中谍15在线观看免费版高清| 中途岛之战 电影| 瓜达卢佩的玫瑰女邻居| 美丽的小蜜桃9| 美人为馅第二季| 《女超人-麦乐迪》| 河山电视剧在线观看| 王牌贱谍| 蛋蛋走乡村| 我要和你在一起电视剧全集完整版| 完美女人免费观看完整版高清| 挠女孩的脚心| 除却巫山| 美景之屋2迅雷下载| 家属动漫1~6全集在线播放| 暴躁老妈第50集免费观看| 王牌对王牌第一季免费观看完整版| 黑桃视频| 流浪地球1免费观看完整版| 看电影电视剧好网站最新电影电视剧| 高清家庭计划2| 香瓜七兄弟第一季| 亲爱的客栈2| 向东是大海百度影音| 电影《需要爸爸播种子》HD中字在线观看,高清完整版美国倫理片_努努影院 | 学生妈妈5字| 举起手来第二部| 欢乐家长群40集免费播放| 高清寄往电视台的神秘影像未删减| 潍坊科技学院是几本| 电影《韩国财阀》完整版| 后妈韩剧| 房奴试婚开头原声| 忒弥斯的不确定法庭| 小瘦子2在| 陕西卫视回看| 桂林小张| 阴阳镇怪谈在线观看免费完整版 | 国模思思| 最美的时光番外二| 生日快乐刘若英版电影| 满天星《瓜达卢佩的玫瑰》电影免费| 皮囊之下电影完整高清在线播放| 1995版《激战丛林》在线观看| 一世真爱情免费观看全部电视剧| 需要爸爸的种子bd| 东方侠客| 家有一老全集| 经山历海| av收藏之家| 法国伦理高压监狱2| 色女仆网站| 我的xl司令在线观看免费高清全集| 上海上海电视剧| 需要爸爸播种英文免费看| 地牢女孩在线观看完整版高清 | 大地10中文在线观看免费版高清| 冷暖人生路| 四少妇按摩记电影| 一网打尽 印度电影| 鹿鼎记陈小春版演员表| 南宫市| 满天星《法国女仆》在线| 吧l啦啦小魔仙之彩虹心石| 异形vs人类| 种马猎人3电影免费| 白峰在线观看完整| 进球吧少年| 火拼全集观看| 美国5~1普通话| 日剧电影维修工人的艳遇| 色无极影视 影院| 团鬼六美容师招聘| 迷宫星莱克尔在线观看高清版| 大胸特殊按摩电影| 日和漫画中文配音| 终极斗士3在线观看完整版免费| 金牌销售秘密5HD中字| 日本jiZZ视频| 名侦探柯南18异次元的狙击手| 星空电影在线观看播放免费| 聊斋奇谭3之妖女谭2普通话| 金银瓶1-5hd普通版2| 酷六电影网| 代表建议严炒作网红儿童账号| 妈妈看上儿子的同学韩剧叫什么| 需要爸爸播种子bd中字| 熊猫越狱| 电影男与女免费星辰| 建始县| 1—5集普通话版免费下载| 别让爱你的人等太久电视剧免费观看| 魔幻车神| 《误杀》电影完整版| 《法国空乘4》免费完整版| 活埋电影免费完整视频| 夜来香电影在线看| 迷茫管家与懦弱的我第二季| 牙医姐妹完整版观看| 飞屋环游记高清| 田姐辣妹电视剧全集免费观看| 保罗和雪梨一家1| 快乐再出发第一季综艺免费观看| 电影《招待外卖员》免费播放| 欢迎来到实力至上第二季樱花动漫| 一休哥动画片免费观看全集| 锵锵锵锵锵锵锵免费观看完整版大全 | 战狼4完整免费观看在线播放版| 星球大战原力释放| 地狱默示录| 壮志凌云满天星| 《家庭矛盾4》麦乐迪完整版| 犯罪心理第十季| 黑暗荣耀电视剧| 三年大片全免费观看国语版 | 《魅魔姐姐》动集观看| 爸爸的种子高清免费版电视剧| 《法国娃娃脸》高清| 狂飙高清在线观看| 青春 裴斗娜版| 美国式禁忌矿桥矿影视| 三年大片免费观看大全国语| 误杀3在线播放| 菊色宫先锋影音| 电影太极2英雄崛起| 陈宝莲电影| 人世间 纪录片| 聊斋李月华免费播放| 人鱼小姐国语版在线观看免费全集| 金牌销售秘密1HD中字| 禁止的爱善良的小姨在线播放免费 | 《美容院1:特殊待遇》在线观看| 洪武双雄| 反击第一季| 为奴12年| 正在播放:黑人巨屌 Karla Kush 金发美女对战大黑鸡巴 - 17 | 特利迦奥特曼免费观看全集普通话| 村妓经典k8| 上海夜莺| 雪中悍刀行第二部免费观看完整版| 即刻上场电视剧免费观看| 韩剧《爷爷与媳妇》剧情介绍分集| 爱情大片免费观看全集| 继拇再也忍不住了HD| 李恩美女友妈妈| 《交换夫婦》木下凛凛子中文字幕在 | 渔夫荒野史记1988版七| 你的名字在线观看免费高清完整版| 6708杏色水蜜桃| 你微笑时很美电视剧免费观看| 我的女婿| 海角在线观看| 奥特曼兄弟国语版| 现在我们相爱吗| 灵异事件簿| 《法国空组》4| 断魂小丑在线观看完整版| 婚姻攻略全集免费观看| 爱壹帆电视剧| 《最高の爱人沼》三上悠亚| 女子在石缝中发现野生西瓜| 蒋玲玲版《渔夫的荒野史记》剧在线| 奔跑吧兄弟白鹿h5部分1–5| 寡妇女人免费观看全集高清电视剧| xl司令第一赛季真人版播放| 时光代理人第二季| 银河护卫队2电影天堂| 风吹半夏在线免费观看| 电影《美味快递员2》| 乒乓球女团决赛直播| 人世间电视剧全集在线观看完整版| 坠落的女律师在线观看完整版 | 快乐到死电影在线观看| 麦乐迪·马克斯 女超人| 净最新影片在线看| 艰难爱情全集免费观看| 四位少妇按摩的电影| 致命愿望在线观看免费全集电视剧| 百度战曲| 《私人航空》法国电影免费观看完整版| 双性受抽搐潮喷调教老师与学生| 将门嫡女沙场:不输男儿郎短剧全集| 私人女性监狱电视剧完整版观看免费| 繁华落尽网剧| 旺角卡门| 吉尔莫女孩第二季| 露营后营露宿第一季未增减0.0.0| 女同地带| 薛丁山电视剧免费看| 特殊治疗室| 纵有疾风起在线播放| 电影心灵奇旅| 《美丽妻子替弟还债》剧免费观看| 简单任务| 王祖贤视频| 战狼6欧式少女全部剧情介绍大全视频| 热情邻居电影免费播放全集在线看| 电影 大玩家| 四个少妇全身稞体精油按摩 | 法国《飞翔女孩》| 我年轻瘦子9| 破密 电视剧| 电影玩物| 独步逍遥在线观看| 一站到底檀越是哪一期| 暴躁老妈免费观看全集| 《重返狼群》10周年特别版| 云岭茉莉白是什么茶| 女员的付出中字1230| 欧洲性旅行百度影音| 栋笃特工| 贝拉1980免费高清原声满天星美版| 《帕克》| ons俱乐部| 年轻的母亲4线手在线播放| 小旅馆的肥熟老女人| 色九月 在线播放| 倾城电影| 初见乍惊欢| 两生花片花| 女保险公司推销员8中文手机| 不是不想嫁剧情介绍| 战狼6免费观看在线播放下载电影视频| 类似3d肉蒲团的电影| 苍天有眼演员表| 小辣椒3结局| 生命缘李华| 金装的维尔梅樱花动漫第一季| 灵笼第二季免费观看完整版| 黄色仓库里的电影| 还珠格格新| 欧式少女10集全观看战狼6| 别打扰我读书电视剧结局免费观看 | 八仙饭店2埃博拉病毒| 黄品冠的老婆| 辣妈犟爸| 韩国三级片有求必应| 隐秘的角落电视剧在线播放| 李玟墓地杂草已被清除| 高清《美景之屋1》| 牙狼garo 炎之刻印| 星克莱尔| 离婚前规则李小萌| 在韩国成为房主的方法未删减| 需要妈妈的种子| 贵妇人街电影版免费观看中文| 乡村老板:致富全村短剧全集 | 风火雷电破手势图解| 女超人 满天星版麦乐迪马克斯 | 小王子 2015 电影| 凶城计中计粤语| 末代御医粤语| 荷尔蒙6电影在线观看免费 | 秦岚八卦| 仁心解码2粤语24| 《家属》| 高清年少有为| 长月无烬免费观看完整版| 兰花花电视剧完整版免费观看| 嘉峪关市| 美国空乘2019电影完整免费高清原声奔跑吧中文字幕 | 18jack| 。金银15美国欧式少妇16集全电视| 我的姐妹免费韩剧电视剧| 我的机器人女友国语| 基层风云| 末日之热浪来袭短剧| 《女超人-麦乐迪版》| 劈雳mit| 鱼水情歌| 法国空乘4免费完整版在线播放| 《堕落的修女》完整版| 有个地方只有我们知道| 360天大佬爱上第二季| 疯人院电视剧在线观看免费完整版| 名侦探柯南沉默的十五分钟| 法航空乘11| 《4位少妇精油按摩记》 | 越南女兵| 与恶魔有约电视剧| 笔仙咒怨| 甜蜜惩罚之我是看守所专用宠物| 啄木鸟《荣誉法则》凯登斯托雅| 《兄弟换麦子6国语版1080P》bd影视免费在线观看 - 云端影库 | 英剧《情劫》电影版| 爱子情深全集| 安斋拉拉躲雨电影免费观| 西环浮尸| 蒙娜丽莎走下楼梯| 团鬼六女教师绳地狱| 黑话律师第五集在线观看| 唐璜的回忆| 电影《美容院的特殊待遇》3演员表2022| 傲骨贤妻 第五季| 电视剧夫妻密码| 谍战剧《梅花红桃》开机| 唐伯虎在线vlog免费观看全集中文| 窈窕淑女免费观看完整版| 男与女在线观看| 海军大院| 余庆县| 驯服小姨子2在线观看 | 三年电影在线观看高清| 公交车艳妇系列1一40| 爱情的牙齿| 出差被讨厌的部长侵犯| 男生和女生愁愁愁电视剧在线观看网页版| 忽而今夏1| 《悲伤恋歌》电视剧| 飞行船奇遇记| 邝美云大悲咒歌词| 再次见到你电视剧免费观看| 扫黑风暴连续剧| 姐姐的朋友2在线观看| 睫毛膏3准北电影网| 八角笼中免费观看全集| 高清《为你遗憾》电影| 八零搞钱:重生宠妻短剧全集| 姐姐6免费完整高清电视剧在线看| 和继拇做爰HD中字| 电视剧花非花雾非雾全集| overflow第一季樱花动漫 | 日本海鲜滞销堆积成山| 铁血柔情短剧免费观看完整版| 尽管如此千辉同学也太甜了| 泰剧《蛇姬恋》免费观看| 第八个嫌疑人演员表| 女大学生的心理沙龙室| 蛇姬恋完整版在线观看| 梦戏巴黎电影完整版高清在线观看| 断魂小丑3在线播放| 《私人航空2》在线看| G点1985无删减免费看| 吴邪的私家笔记免费观看| 完美小歪| 满天星女版唐三藏| 《咒》2022免费观看| 被甩继承:亿万家产短剧全集| 金牌销售秘密5HD| 加勒比女海盗2观看高清完整版| 校园兔女郎迅雷下载| 九重紫电视剧在线播放视频观看高清| 谈情说案电视剧| 韩国短剧隐身帽子完整版| 斗罗大陆免费完整版| 金瓶梅全集| 华丽的外出全集| 命转乾坤电视剧国语| 满天星电影在线观看完整| 人犬兽人100集全部| 孟丽君之再生缘| 上海滩主题曲简谱| 美女脱去衣游戏| 金银梅5一10普通话版免费观看第10集| 《刺激的瑜伽教练3》| 史蒂夫乔布斯传 pdf| 神武主题曲| 西游记女儿国电影免费观看高清 | 电锯人蕾塞篇剧场版观看| 后来的我们短剧免费观看完整版| 千山暮雪第一集| 漂亮妈妈7中字开头歌曲| 三级维修工的艳遇| 火遮眼未删减| 《快乐到死》电影| 定州市| 声生不息免费观看完整版| 高清《狼人游戏》歌曲原唱| 徐以若方发律师函否认殴打赵露思| 女超人法国电影完整在线观看| 欧式少女18集全集在线看 | 深海利剑电视剧| 黑帮少爷爱上我第10集在线观看| 堕落的律师电影完整版剧情| EEuSS| 电视连续剧暗战| 《马腾你别走》| 在线看《美容院的特殊待遇》| 石敢当之雄峙天东演员表| 电视剧夜深沉| 你懂的369| 电影《一路西向》| 华人城另类小说| 地狱奶奶| 花样男子25| 女战狼6免费高清版 | 沃客装修| 木下凛凛子电影| 《上门服务》菲律宾主演是谁| 少帅张学良电视剧| 勇敢的心电视剧全集在线观看76| 林采缇视频种子| 黑暗荣耀第一季无删减在线观看 | 佐佐木希av作品| 芝麻胡同免费观看全集剧情| 到吴起镇大合唱| 双人调情按摩电影在线观看| 我的小姨全集在线观看 | 哇嘎嘎免费观看在线播放| 2010《暮光同城》双男主| 极速恋人第二季未删减版第15集 | 电影私人航空完整版播放| jordan大战黑人| 新还珠格格98集| 儿子的妻子 电影中文字| 花与蛇全集| 美丽小瘦子7| 文成公主王庆爽| 聊斋志异之电影大全| 战狼6电影在线观看免费版高清| 特别治疗特殊待遇2| 邵氏电影武打片| 电视剧全集免费看| 营销技巧电影在线观看| 漂亮的保姆HD电影| 神墓在线观看全集免费观看动漫| 不能错过你电影免费观看| 地球上的爱人| 华人城另类小说| 迷失太空电影免费观看| 柳州记电视剧在线观看| 花与蛇4下载| 恶搞之家第2季| 特殊的游泳教练在线观看中字| 为您服务| 燃冬电影高清在线观看免费| 《被拒绝的爱》结局| 大胸年轻继拇5免费| 高清《大秦帝国》| 哪啊哪啊神去村| 东方侠客免费观看全集| 鸟的天堂教案| 达日县| 年经继4| 博格丹和女飞行员徐枫灿合影敬礼| 同班同学在线电影免费观看完整版| 女人的抉择在线观看| AIGAO网在线观看| 女销售员的销售秘密2| 安吉拉·怀特 透视| 为时已是寿司!?全集观看| 李连杰电影全集高清| 超异能族 电视剧| 爱情保卫战 海霞姐| 丫头 5| 《夫债妻偿》在线观看全集| 幼儿园男童送女孩200克金条| 亲爱的热爱的免费版全集| 泽塔奥特曼普通话免费版在线观看| 刘青云电影全集| 《修理工的艳遇》| 壮志凌云2法国满天星播放技巧| 飞哥大英雄免费版在线播放| 小越勇辉| 暴躁46集全在线观看免费高清/1| 长江七号爱地球电影| 护国良相狄仁杰| 战锤40k电影在线观看完整版| 花木兰 高清| 《维修人员的培训》全集完整版免费| 嘿小可爱| 橘梨纱 快播| 古惑仔少年激斗片| 高压监狱2法版1小时43分| 平泽里菜子| 情难自制在线| 开心宝贝5部| 男生女生一起愁愁愁全部电视剧观看| 乳房影院| 电视剧心想事成| 青岛一酒店疑闪爆| 任达华舞男| 坎贝奇的《无憾》电影在哪里看的| 需要爸爸的播种 在线观看 | 像乔丹一样打球| 爱我几何无删减在线免费观看| 电视剧幻影| 伪装者电视剧全集观看| 蒙面超人| 睡觉身体下边突然很舒服| 我和房东在做爰电影| 徐梦桃高喊我是第一吗| 电影观看免费观看完整版高清| 笑傲江湖征战纵女| 维修工的绝遇3| 三姐妹招聘男保姆| 天使的诱惑| 羁绊5.3| 柯淳的短剧| 韩国理伦片驯服小峓子2在线观看| 韩媒曝刘亚仁男友潜逃海外失败| 武则天秘史快播| 格里高利教皇合唱团| 神奇宝贝2| omoflow第一集真人版免费观看| 哪吒电影第二部| 变形金刚2百度影音| 白蛇传说在线观看| 正安县| 正在播放:【夏晴子&温芮欣】国风按摩院_年节双飞俏佳丽 | 胜算电视剧免费完整版| 今生也是第一次电视剧| 楚剧大全| 黑白配高清视频播放| 铁猴子传奇之怒火狼牙| 引诱我的巨乳女邻居| 南充属于几线城市| 那小子真酷| 草灯和灯电影完整版| 月嫂剧情| 越狱兔第5季| 斗罗大陆动漫全集| 蜈蚣咒未删减版完整版恐怖电影| 《初体验5》完整版免费观|