1. 安裝curl和libcurl
Linux部分機器自帶curl,可以直接使用,但不會包含curl庫,且有些版本過舊,所以仍然建議下載最新版本curl使用
(1)獲得安裝包(官網http://curl.haxx.se/)
本文列出不一定是當前最新版,到官網查詢最新版本鏈接自行更改即可
# wget http://curl.haxx.se/download/curl-7.65.1.tar.gz
(2)解壓
# tar -zxf curl-7.65.1.tar.gz
(3)進入解壓後的目錄
# cd curl-7.65.1
(4)配置文件
一般無需設置直接使用默認配置即可,建議不要修改安裝路徑,否則後續還需自行添加include路徑,若需指定安裝路徑,使用–prefix參數
# ./configure --prefix=/usr/local/curl
其餘的配置的使用可通過./configure --help
查看
建議安裝之前先查看當前目錄下的README、GIT-INFO、INSTALL文件,許多不可預測的問題都能在此找到答案
(5)make
# make
# make install
(6)檢查版本
# curl --version
版本信息與安裝版本相符則到此步驟已經安裝成功
(*)將curl命令加入環境變量
(如果按照默認路徑安裝則無需執行此步驟)
僅對本會話起作用,或者在.bash_profile、.bashrc文件裏配置環境變量
# export PATH=$PATH:/usr/local/curl/bin
(*)添加curl.h到include路徑
(如果按照默認路徑安裝則無需執行此步驟)
# cp -r /usr/local/curl/include/curl /usr/include
(*)C/C++調用libcurl
到/usr/local/lib/或指定的安裝路徑,即可查看到安裝好的庫文件
若要include庫文件可如下編寫
#include <curl/curl.h>
可根據參考文獻2中代碼測試libcurl
需要注意在編譯過程中一定要加入 -lcurl 參數,否則將出現鏈接錯誤,如g++ main.cpp -o main -lcurl
2. curl命令的簡單實用
以下命令爲curl與localhost通訊進行上傳和下載文件
# curl -v -X PUT http://localhost/doc/1.txt -T 2.txt
# curl -v -X GET http://localhost/doc/1.txt -o 2.txt
選項-v
或--verbose
爲顯示詳細操作信息,建議剛開始使用時加上,能爲調試提供很大幫助。
其餘選項的使用可以使用curl --help
或man curl
查看幫助信息,每個選項都有詳細的說明。(中文翻譯)
curl命令能爲之後curl庫的使用提供參考基礎,建議在進行curl代碼編寫前先使用curl命令實現,有些時候的bug不是代碼造成的,有可能本身curl就無法建立連接。
3. curl庫的調用
libcurl主要提供了兩種發送http請求的方式,分別是Easy interface方式和multi interface方式,前者是採用阻塞的方式發送單條數據,後者採用組合的方式可以一次性發送多條數據
libcurl傳輸任務流程如下(其中最重要的是3和4步):
- 1 調用
curl_global_init()
初始化libcurl - 2 調用
curl_easy_init()
得到easy interface型指針(句柄) - 3 調用
curl_easy_setopt()
設置傳輸選項 - 4 根據
curl_easy_setopt()
實現回調函數 - 5 調用
curl_easy_perform()
傳輸數據 - 6 調用
curl_easy_cleanup()
清空句柄 - 7 調用
curl_global_cleanup()
釋放內存
#include <curl/curl.h>
#include <string>
#include <iostream>
using namespace std;
int httpPutFile() {
CURL* curl = NULL;
CURLcode result = CURLE_OK;
string url = "http://10.5.201.200:8080";
FILE* inputFile = fopen("./put.txt", "rb");
string outputFilename = "/1.txt";
url += outputFilename;
//HttpHead
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "endPoint:http://10.5.201.200:8080");
headers = curl_slist_append(headers, "accessKeyId:yealink");
headers = curl_slist_append(headers, "secretAccessKey:hhh12345");
headers = curl_slist_append(headers, "Authorization:yealink:Signature=abcd");
//Init
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
//Option
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_INFILE, inputFile);
//curl_easy_setopt(curl, CURLOPT_INFILESIZE, 87);
curl_easy_setopt(curl, CURLOPT_PUT, 1);
//PUT鐨勬枃浠跺繀欏誨湪INFILE錛孖NFILESIZE涓緗紝涓嶄嬌鐢‵ILE鐨凱UT闇€鐢–URLOPT_CUSTOMERQUEST瀹炵幇
//curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
//Perform
result = curl_easy_perform(curl);
//Clean
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
int httpGetFile() {
CURL* curl = NULL;
CURLcode result = CURLE_OK;
string url = "http://10.5.201.200:8080";
FILE* outputFile = fopen("./get.txt", "wb");
string inputFilename = "/1.txt";
url += inputFilename;
//HttpHead
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "endPoint:http://10.5.201.200:8080");
headers = curl_slist_append(headers, "accessKeyId:yealink");
headers = curl_slist_append(headers, "secretAccessKey:hhh12345");
headers = curl_slist_append(headers, "Authorization:yealink:Signature=abcd");
//Init
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
//Option
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)outputFile);
//Perform
result = curl_easy_perform(curl);
//Clean
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return 0;
}
int main(int argc, char* argv[]) {
string method = argv[1];
if(method == "PUT" || method == "put") {
httpPutFile();
}else if(method == "GET" || method == "get") {
httpGetFile();
}else {
cout << "Method error, please input \"PUT\" or \"GET\"." << endl;
}
cout << endl;
return 0;
}