#include
#include
/* mutil 句柄的最大连接数 */
#define MAX_CONNECT_HANDLE_NUMS (15)
/* 客制化的私有数据结构体 */
typedef struct CustomPrivData
{
curl_mime *mime;
struct curl_slist *headers;
FILE* wfd;
}CustomPrivData;
curl_global_init(CURL_GLOBAL_ALL);
CURLM * m_MultiHandle = curl_multi_init();
curl_multi_setopt(m_MultiHandle, CURLMOPT_MAXCONNECTS, MAX_CONNECT_HANDLE_NUMS);
CURLSH* m_ShareHandle = curl_share_init();
if(m_ShareHandle)
{
/* 设置DNS共享,不然每个easyhandle执行时都要解析一遍DNS */
curl_share_setopt(m_ShareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
}
CURL* EasyCurlHandle = curl_easy_init();
if(EasyCurlHandle)
{
curl_easy_setopt(EasyCurlHandle, CURLOPT_FOLLOWLOCATION, 1L);
struct curl_slist *headers = NULL;
char Auth_header[256]={0};
snprintf(Auth_header, 256, "Authorization:Bearer %s","test21334242");
headers = curl_slist_append(headers, Auth_header);
CustomPrivData* PrivData = new CustomPrivData;
memset(PrivData, 0, sizeof(CustomPrivData));
//headers = curl_slist_append(headers, "User-agent:Mozilla/5.0(Windows NT 6.1;Win64; x64)");
//headers = curl_slist_append(headers, "Accept-Encoding:gzip,deflate");
//headers = curl_slist_append(headers, "Accept-Language:zh-CN,zh;q=0.9");
curl_easy_setopt(EasyCurlHandle, CURLOPT_HTTPHEADER, headers);
PrivData->headers = headers;
/* 设置DNS cache的超时时间为120s */
curl_easy_setopt(EasyCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 60*2);
curl_easy_setopt(EasyCurlHandle, CURLOPT_SHARE, m_ShareHandle);
curl_easy_setopt(EasyCurlHandle, CURLOPT_URL, url); /* URL地址设置 */
curl_easy_setopt(EasyCurlHandle, CURLOPT_NOSIGNAL, 1L);
//curl_easy_setopt(m_EasyCurlHandle, CURLOPT_WRITEFUNCTION, NULL);
//curl_easy_setopt(m_EasyCurlHandle, CURLOPT_WRITEDATA, NULL);
curl_easy_setopt(EasyCurlHandle, CURLOPT_VERBOSE, 1);
curl_easy_setopt(EasyCurlHandle, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(EasyCurlHandle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(EasyCurlHandle, CURLOPT_DEFAULT_PROTOCOL, "https");
curl_mime *mime;
curl_mimepart *part;
mime = curl_mime_init(EasyCurlHandle);
part = curl_mime_addpart(mime);
curl_mime_name(part, "file");
curl_mime_filedata(part, file_path);
curl_easy_setopt(EasyCurlHandle, CURLOPT_MIMEPOST, mime);
PrivData->mime = mime;
/* 设置私有数据用于curl_multi_perform执行后区分不同easy句柄 */
curl_easy_setopt(EasyCurlHandle, CURLOPT_PRIVATE, PrivData);
/* 添加到multi句柄 */
curl_multi_add_handle(m_MultiHandle, EasyCurlHandle);
/* headers、mime不能在此处释放 ,否则调用multi接口时奔溃*/
//curl_slist_free_all(headers);
//curl_mime_free(mime);
}
以上有两点注意:
1)、使用share接口实现DNS共享,加快处理速度;
2)、使用curl_easy_setopt(EasyCurlHandle, CURLOPT_PRIVATE, PrivData)设置私有数据,用于curl_multi_info_read调用之后区分不同的easyhandle;
《2》、开启线程处理函数
void* MultiperformFunc(void* ptr)
{
m_IsStillRuning = true;
int msgs_left = 0;
int still_running = 0;
while(m_IsStillRuning)
{
CURLMcode mcode = curl_multi_perform(m_MultiHandle, &still_running);
while(mcode == CURLM_CALL_MULTI_PERFORM)
{
cout << "................ CURLM_CALL_MULTI_PERFORM ..............";
mcode = curl_multi_perform(m_MultiHandle, &still_running);
}
//LOG_DEBUG << "still_running: " << still_running;
CURLMsg *msg = NULL;
int numfds = 0;
/* wait for activity, timeout or "nothing" */
int res = curl_multi_wait(m_MultiHandle, NULL, 0, 1000, &numfds);
while((msg = curl_multi_info_read(m_MultiHandle, &msgs_left)))
{
if(msg->msg == CURLMSG_DONE)
{
CustomPrivData* PrivData = NULL;
CURL *e = msg->easy_handle;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &PrivData);
//fprintf(stderr, "R: %d - %s <%s>\n",msg->data.result, curl_easy_strerror(msg->data.result), wfd);
if(PrivData)
{
/* 处理每个easyhandle的私有数据 */
if(PrivData->wfd)
fclose(PrivData->wfd);
if(PrivData->headers)
curl_slist_free_all(PrivData->headers);
if(PrivData->mime)
curl_mime_free(PrivData->mime);
delete PrivData;
PrivData = NULL;
}
/*当一个easy handler传输完成,此easy handler仍然仍然停留在multi stack中,
调用curl_multi_remove_handle将其从multi stack中移除,然后调用curl_easy_cleanup将其关闭*/
curl_multi_remove_handle(m_MultiHandle, e);
curl_easy_cleanup(e);
}
else
{
//fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
cout << "curl Error: " << msg->msg;
}
}
usleep(30*1000);
}
}
《1》、libcurl采用curl_multi_perform() + curl_multi_wait()方式实现异步高性能l发送数据的方法
《2》、libcurl的share interface与curl_easy_perform的性能