libcurl__001__学习easy接口(一)__获取URL内容
编译器: MinGW64 (GCC)
构建工具: CMake + Ninja
依赖库: libcurl
实现步骤:
① 全局初始化
函数:curl_global_init(CURL_GLOBAL_ALL)
② 创建句柄
函数:curl_easy_init()
③ 设置必要选项
函数:curl_easy_setopt()
④ 清理资源
说明:如果资源创建成功,创建资源和清理资源应该成对出现
函数:curl_easy_cleanup()
CMakeLists.txt
1 2 3 #声明CMake和C++的最低版本要求 4 cmake_minimum_required(VERSION 3.10.0) 5 set(CMAKE_CXX_STANDARD 11) 6 7 #定义项目的基本信息 8 project(realtime_scene_analyzer VERSION 0.1.0 LANGUAGES CXX) 9 10 #启用CTest测试框架 11 include(CTest) 12 enable_testing() 13 14 #查找系统中安装的OpenCV库 15 find_package(OpenCV REQUIRED) 16 find_package(CURL REQUIRED) 17 18 #创建一个可执行文件目标 19 add_executable(RSA test01.cpp) 20 21 #将库链接到可执行目标 22 target_link_libraries(RSA 23 ${OpenCV_LIBS} 24 CURL::libcurl 25 ) 26 27 #设置CPack打包工具的项目名称 28 set(CPACK_PROJECT_NAME ${PROJECT_NAME})
test01.cpp
#include <iostream> #include <string> #include <curl/curl.h> // 引入 libcurl 头文件 // 1. 定义回调函数:这是 libcurl 的核心机制 // 当 libcurl 接收到数据时,它会调用这个函数 // 注意:在 C++ 中,这个函数必须是全局函数或者静态函数,不能是普通类成员函数 /* * 参数说明: * ptr: libcurl 传给你的数据指针(这就是下载下来的数据) * size: 每个数据块的大小(通常为 1) * nmemb: 数据块的数量 * userdata: 你自己传进来的参数(我们在下面会传一个 string 的地址进去) */ static size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *userdata) { // 将 void* 转换回我们熟悉的 string& std::string &response_string = *(static_cast<std::string*>(userdata)); // 计算数据总长度 size_t total_size = size * nmemb; // 将数据拷贝到 string 中 response_string.append(static_cast<char*>(ptr), total_size); // 必须返回处理的字节数,否则 libcurl 会认为出错并停止下载 return total_size; } int main() { // ==================== 第一步:全局初始化 ==================== // 这个只需要在整个程序生命周期中调用一次 //curl_global_init负责初始化网络库 //CURL_GLOBAL_ALL用于初始化所有能被初始化的功能 CURLcode res = curl_global_init(CURL_GLOBAL_ALL); if (res != CURLE_OK) { std::cerr << "libcurl 全局初始化失败: " << curl_easy_strerror(res) << std::endl; return 1; } // ==================== 第二步:创建 Easy Handle ==================== //句柄:本质是一个不透明的指针或表示符,用来代表某个内部对象,开发者不需要关心内部的工作逻辑,只需要知道如何使用即可 // 每一个传输任务都需要一个独立的 Handle CURL *curl = curl_easy_init(); if (!curl) { std::cerr << "Easy Handle 创建失败" << std::endl; curl_global_cleanup(); return 1; } // 准备一个字符串,用来接收下载回来的网页内容 std::string response_data; // ==================== 第三步:设置各种选项 (Options) ==================== //curl_easy_setopt()中第一个参数是句柄,第二参数是选项类型(声明要设置的是功能),第三个参数是可变参数,也就是同一个函数可以根据类型第二个参数的不同,接收不同类型的第三个参数(这里第三个参数是声明把功能设置成什么样) // 3.1 设置要访问的 URL curl_easy_setopt(curl, CURLOPT_URL, "http://httpbin.org/get"); // 3.2 设置超时时间(秒),防止程序卡死 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // 3.3 设置回调函数:告诉 libcurl "收到数据后把数据交给谁处理" // WriteCallback 就是我们上面定义的那个函数 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); // 3.4 设置回调函数的第四个参数 (userdata) // 这里我们将 response_data 的地址传进去,这样 WriteCallback 就能把数据写进这个变量 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data); // ==================== 第四步:执行任务 ==================== // curl_easy_perform 是阻塞的,它会一直等到下载完成或出错才返回 //它会执行的功能: // 建立网络连接(DNS解析、TCP握手、TLS握手) // 发送HTTP请求(GET/POST等) // 等待服务器响应 // 接收数据(通过你设置的回调函数处理数据) // 返回结果(成功或失败) res = curl_easy_perform(curl); // 检查执行结果 if (res == CURLE_OK) { // 任务成功,打印状态码和内容 long http_code = 0; // 获取 HTTP 状态码 //这里也使用了可变参数 //用指针接收要获取的数据 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); std::cout << "HTTP 状态码: " << http_code << std::endl; std::cout << "下载内容: " << std::endl << response_data << std::endl; } else { // 任务失败,打印错误信息 //curl_easy_strerror(res)把错误代码转化成人类可读的信息 std::cerr << "下载失败: " << curl_easy_strerror(res) << std::endl; } // ==================== 第五步:清理资源 ==================== // 先清理 Easy Handle curl_easy_cleanup(curl); // 最后清理全局资源(通常在程序退出时调用) curl_global_cleanup(); return 0; }
结果如图:


浙公网安备 33010602011771号