libcurl 是功能強大的 URL 傳輸庫,支援 HTTP、HTTPS、FTP、FTPS、SFTP 等協定。本文聚焦 Easy 介面(同步、單執行緒),足以應對多數下載/上傳需求。
CURL *curl = curl_easy_init(); // 1. 初始化 curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/file.zip"); // 2. 設定選項 curl_easy_perform(curl); // 3. 執行傳輸 curl_easy_cleanup(curl); // 4. 清理資源
curl_global_init(CURL_GLOBAL_DEFAULT); // 載入 SSL、WinSock 等 // ... 使用 curl_easy_* ... curl_global_cleanup();
CURL_GLOBAL_ALL:全部子系統(SSL、Win32、IDN 等)。CURL_GLOBAL_SSL:僅 SSL/TLS。CURL_GLOBAL_WIN32:僅 WinSock。CURL_GLOBAL_NOTHING:不初始化(手動管理)。| 函式 | 說明 |
|---|---|
curl_easy_init() | 建立 handle,回傳 CURL*;失敗回傳 NULL。內部會自動呼叫 curl_global_init(若未初始化),但建議手動控制。 |
curl_easy_cleanup(handle) | 釋放 handle 相關資源(連線、SSL session、DNS cache 等)。必須成對呼叫。 |
curl_easy_duphandle(handle) | 複製 handle(含所有選項),不複製狀態(連線、SSL、cookies)。新 handle 仍需 cleanup。 |
curl_easy_reset(handle) | 重置 handle 到初始狀態(保留連線、DNS、cookies、share)。 |
CURLcode curl_easy_setopt(CURL *handle, CURLoption option, ...);
所有行為透過 option + 參數控制。常用選項:
| 選項 | 參數類型 | 用途 |
|---|---|---|
CURLOPT_URL | char* | 目標 URL |
CURLOPT_WRITEFUNCTION | callback | 資料寫入回呼 size_t (*)(char*, size_t, size_t, void*) |
CURLOPT_WRITEDATA | void* | 傳給 WRITEFUNCTION 的 user pointer |
CURLOPT_READFUNCTION | callback | 上傳資料讀取回呼 |
CURLOPT_READDATA | void* | 傳給 READFUNCTION 的 user pointer |
CURLOPT_HEADERFUNCTION | callback | Header 處理回呼 |
CURLOPT_TIMEOUT | long | 整體逾時(秒) |
CURLOPT_CONNECTTIMEOUT | long | 連線階段逾時(秒) |
CURLOPT_FOLLOWLOCATION | long | 自動追蹤 3xx 重導向 (1=開啟) |
CURLOPT_SSL_VERIFYPEER | long | 驗證伺服器憑證 (0=跳過,測試用) |
CURLOPT_USERAGENT | char* | 自定 User-Agent |
CURLOPT_POST | long | 啟用 POST (1=POST) |
CURLOPT_POSTFIELDS | char* | POST 資料內容 |
CURLOPT_HTTPHEADER | struct curl_slist* | 自定 HTTP Header 串列 |
CURLOPT_ERRORBUFFER | char* | 錯誤訊息緩衝區 (需 ≥ CURL_ERROR_SIZE) |
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl error: %s\n", curl_easy_strerror(res));
}
// 取得傳輸資訊
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
double total_time;
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time);
curl_off_t download_size;
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD_T, &download_size);
#include <stdio.h>
#include <curl/curl.h>
size_t write_callback(void *ptr, size_t size, size_t nmemb, FILE *fp) {
return fwrite(ptr, size, nmemb, fp);
}
int main() {
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) return 1;
FILE *fp = fopen("download.zip", "wb");
if (!fp) { curl_easy_cleanup(curl); return 1; }
curl_easy_setopt(curl, CURLOPT_URL, "https://speed.hetzner.de/100MB.bin");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 300L); // 5 分鐘逾時
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK) fprintf(stderr, "Download failed: %s\n", curl_easy_strerror(res));
fclose(fp);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
curl_easy_escape/curl_easy_unescape(記得 curl_free 釋放結果)。curl_easy_pause(handle, CURLPAUSE_RECV|CURLPAUSE_SEND)。curl_easy_recv/curl_easy_send(需 CURLOPT_CONNECT_ONLY)。curl_multi_*),支援非同步、單執行緒管理多連線。CURLE_OK 才成功;錯誤碼對應 curl_easy_strerror。CURLOPT_SSL_VERIFYPEER=1、CURLOPT_SSL_VERIFYHOST=2。size_t (*)(char*, size_t, size_t, void*),回傳實際處理位元組數;返回 0 非錯誤,表示「暫無資料」。curl_off_t 相關選項(CURLOPT_INFILESIZE_LARGE 等)。curl_easy_cleanup,最後 curl_global_cleanup;切勿在 global cleanup 後仍使用 handle。libcurl Easy 介面簡潔而強大,掌握核心流程與關鍵選項,即可快速實作健壯的 HTTP/HTTPS/FTP 客戶端。複雜場景(並發、非同步、WebSocket)請進階學習 Multi 介面與 libcurl 內部架構。