//引入頭文件
#include "curl\curl.h"
#include "curl\easy.h"
下面我們就來說說curl的使用。curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
curl_global_init()用以初始化curl環境,curl_easy_init用來初始化一個easy curl對象。
#ifdef _DEBUG
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
#endif
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
curl_easy_setopt是對easy curl對象進行相關設置,需要設置哪些參數可以自行查閱。這事可以直接使用curl_easy_perform執行curl請求,但這種情況是阻塞的,所以下面我會介紹multi執行併發請求。先來看看代碼
bool CLibcurl::UserLand(const std::string number, const std::string password)
{
std::string strUrl = "http://*******/User/Login"; // 接口地址
CURL *curl;
CURLM *multi_handle;
std::stringstream getstream;
int still_running;
bool IsTrue = false;
struct curl_httppost *formpost = NULL;
struct curl_httppost *lastptr = NULL;
struct curl_slist *headers = NULL;
static const char buf[] = "Expect:";
curl_global_init(CURL_GLOBAL_ALL);
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "username",
CURLFORM_COPYCONTENTS, number.c_str(),
CURLFORM_END);
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "password",
CURLFORM_COPYCONTENTS, password.c_str(),
CURLFORM_END);
curl = curl_easy_init();
multi_handle = curl_multi_init();
if (NULL == curl || NULL == multi_handle) {
IsTrue = false;
goto exit;
}
headers = curl_slist_append(headers, buf);
#ifdef _DEBUG
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
#endif
curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); // 表單
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &getstream);
curl_multi_add_handle(multi_handle, curl);
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &still_running));
while (still_running) {
switch (Select(multi_handle)) {
case -1:
break;
case 0:
std::cout << "timeout" << std::endl;
default:
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &still_running));
break;
}
}
//對接收到的getstream進行處理
exit:
curl_global_cleanup();
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(curl);
curl_formfree(formpost);
curl_slist_free_all(headers);
return IsTrue;
}
下面我們來分析下這個代碼,此處我寫的是一個簡單的提交登陸表單的程序,使用curl_formadd()來構建表單,是不是發現表單構建起來變得很簡單了,突然有了寫javascript的感覺。curl_formadd中的 CURLFORM_COPYNAME,是後臺接收時的字段名,而CURLFORM_COPYCONTENTS則是存儲字段名對應的內容,比如用戶的用戶名,想了解更多可點擊該鏈接。 使用multi前我們還需要用curl_multi_init()先初始化multi,雖然說multi是併發的,但其實它的使用也是非常簡單的,只需將我們上面使用curl_easy_init創建的curl傳入到curl_slist_append的第二個參數中就行了,接下來我們就可以用curl_multi_perform執行multi了,此處使用的是select來對事件進行監聽,並通知curl執行對應操作。
上面代碼中的Select函數代碼如下:
int CLibcurl::Select(CURLM *multi_handle)
{
struct timeval timeout;
int rc;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
// 獲取文件描述符
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
return rc;
}
最後補充下,在構建表單的時候可以將文件傳入表單中
curl_formadd(&formpost, &lastptr,
CURLFORM_COPYNAME, "data",
CURLFORM_FILE, filepath.c_str(), // 文件的所在地址
CURLFORM_END);
可以用這種方法來實現小文件的簡單上傳,curl的用法大致就說到這裏了,想深入研究的朋友可以積極查閱資料。