libcurl异步非阻塞通信的简单使用
最近用到了libcurl异步非阻塞方式进行通信,在此简单记录一下。主要是用curl_multi_perform,libcurl相关文档链接https://curl.se/libcurl/c/curl_multi_perform.html
代码如下:
1 #include <curl.h> 2 #include <chrono> 3 #include <thread> 4 #include <iostream> 5 #include <string> 6 #ifdef _WIN32 7 #include <WinSock2.h> 8 #include <Windows.h> 9 #endif 10 11 struct uri 12 { 13 CURL* easy_handle = NULL; 14 }; 15 16 CURLM* _multi_handle = NULL; 17 bool _is_running = false; 18 19 void check_multi_info() 20 { 21 struct CURLMsg* m = NULL; 22 do 23 { 24 int msgq = 0; 25 m = curl_multi_info_read(_multi_handle, &msgq); 26 if (m && (m->msg == CURLMSG_DONE)) 27 { 28 // 当前easy handle 已接收完所有消息,清除easy handle 29 CURL* e = m->easy_handle; 30 curl_multi_remove_handle(_multi_handle, e); 31 curl_easy_cleanup(e); 32 33 _is_running = false; 34 } 35 } while (m); 36 return; 37 } 38 39 void process() 40 { 41 while (_is_running) 42 { 43 int running_handle_count; 44 while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(_multi_handle, &running_handle_count)) 45 { 46 } 47 48 while (running_handle_count) 49 { 50 timeval tv; 51 tv.tv_sec = 1; 52 tv.tv_usec = 0; 53 54 int max_fd; 55 fd_set fd_read; 56 fd_set fd_write; 57 fd_set fd_except; 58 59 FD_ZERO(&fd_read); 60 FD_ZERO(&fd_write); 61 FD_ZERO(&fd_except); 62 63 curl_multi_fdset(_multi_handle, &fd_read, &fd_write, &fd_except, &max_fd); 64 int return_code = select(max_fd + 1, &fd_read, &fd_write, &fd_except, &tv); 65 if (-1 == return_code) 66 { 67 break; 68 } 69 else 70 { 71 while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(_multi_handle, &running_handle_count)) 72 { 73 } 74 } 75 } 76 77 check_multi_info(); 78 79 std::this_thread::sleep_for(std::chrono::nanoseconds(1)); 80 } 81 curl_multi_cleanup(_multi_handle); 82 return; 83 } 84 85 size_t write_callback(char* buffer, size_t size, size_t nmemb, void* uri) 86 { 87 std::cout << buffer << std::endl; 88 return size * nmemb; 89 } 90 91 size_t header_callback(const char* ptr, size_t size, size_t nmemb, void* uri) 92 { 93 std::cout << "[header_callback] " << ptr << std::endl; 94 return size * nmemb; 95 } 96 97 void test(const char* url) 98 { 99 curl_global_init(CURL_GLOBAL_ALL); 100 101 _is_running = true; 102 std::thread th(process); 103 104 uri _uri; 105 CURL* easy_handle = curl_easy_init(); 106 _uri.easy_handle = easy_handle; 107 curl_easy_setopt(easy_handle, CURLOPT_URL, url); 108 109 // 设置获取返回内容的回调函数 110 curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, write_callback); 111 curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &_uri); 112 113 // 设置获取头信息的回调函数 114 curl_easy_setopt(easy_handle, CURLOPT_HEADERFUNCTION, header_callback); 115 curl_easy_setopt(easy_handle, CURLOPT_HEADERDATA, &_uri); 116 117 curl_multi_add_handle(_multi_handle, easy_handle); 118 119 th.join(); 120 121 curl_global_cleanup(); 122 123 return; 124 } 125 126 int main(int argc, char* argv[]) 127 { 128 if (argc < 2) 129 { 130 std::cout << "usage:" << argv[0] << " <url>" << std::endl; 131 return 0; 132 } 133 134 test(argv[1]); 135 136 return 0; 137 }

浙公网安备 33010602011771号