libcurl 网络请求 —— 在手机上从代码里发 HTTP 请求
libcurl 是什么
libcurl 是一个 C 语言写的、支持 HTTP/HTTPS/FTP/DICT 等协议的客户端库。几乎所有 C/C++ 网络项目用的 HTTP 客户端都是 libcurl——包括 Google 的一些内部项目、Valve 的 Steam 客户端等。
在 Cxxdroid 里发 HTTP 请求
包管理器搜索「libcurl」或「curl」安装。
CMake 链接:
find_package(CURL REQUIRED)
target_link_libraries(myexe PRIVATE CURL::libcurl)
最小可用示例:GET 请求
#include <curl/curl.h>
#include <iostream>
int main() {
curl_global_init(CURL_GLOBAL_ALL);
CURL *handle = curl_easy_init();
if (handle) {
curl_easy_setopt(handle, CURLOPT_URL, "https://httpbin.org/get");
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
CURLcode res = curl_easy_perform(handle);
if (res != CURLE_OK) {
std::cerr << "curl failed: " << curl_easy_strerror(res) << std::endl;
}
curl_easy_cleanup(handle);
}
curl_global_cleanup();
return 0;
}
注意:程序运行时需要 Android 设备能上网(libcurl 本身是离线库,但要访问外部服务器还是需要网络)。
POST JSON 示例
#include <curl/curl.h>
int main() {
curl_global_init(CURL_GLOBAL_ALL);
CURL *handle = curl_easy_init();
const char *json = R"({"name": "Cxxdroid", "platform": "Android"})";
curl_easy_setopt(handle, CURLOPT_URL, "https://httpbin.org/post");
curl_easy_setopt(handle, CURLOPT_POST, 1L);
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, json);
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, curl_slist_append(nullptr, "Content-Type: application/json"));
curl_easy_perform(handle);
curl_easy_cleanup(handle);
curl_global_cleanup();
return 0;
}
异步 vs 同步
Cxxdroid 上默认用同步阻塞模式——请求发出后程序会卡住,等响应回来才能继续。这对简单的 demo 和学习没问题,但如果要做一个带 UI 的网络应用,应该用:
- 多线程:一个线程跑网络请求,主线程画 UI
- Boost.Asio + libcurl 的 multi interface:纯异步,无阻塞
HTTPS 支持
libcurl 预构建版本通常自带 OpenSSL 或 BearSSL 的 TLS 实现,支持 HTTPS 请求。如果 HTTPS 请求报证书验证错误,可以临时加:
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);
生产环境不要这么做——会丧失 HTTPS 的安全性。但学习和本地测试阶段可以用。
Android 网络权限
通过 Cxxdroid 运行的可执行文件不需要单独申请 Android 网络权限——因为它们不是 Android App,而是被 Cxxdroid 进程执行的原生程序,复用 Cxxdroid 的权限。