下面的代码编译并打印响应。
我的问题是:作为表示对象的字符串的响应,如何将"res"转换为字符串或直接转换为 JSON 对象?
#include <stdio.h>
#include <curl/curl.h>
#include <json-c/json.h>
int main(int argc, char **argv) {
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080/system/genpass");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "length: 20");
headers = curl_slist_append(headers, "numbers: true");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
printf("%u",res);
}
curl_easy_cleanup(curl);
}
不能简单地将函数的返回代码转换为字符串。 它们没有任何关系。
相反,您需要直接处理接收到的数据。 为此,您需要注册一个可以处理数据的回调函数。 这在 cURL 手册中有描述。
例:
typedef struct {
unsigned char *buffer;
size_t len;
size_t buflen;
} get_request;
#define CHUNK_SIZE 2048
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t realsize = size * nmemb;
get_request *req = (get_request *) userdata;
printf("receive chunk of %zu bytesn", realsize);
while (req->buflen < req->len + realsize + 1)
{
req->buffer = realloc(req->buffer, req->buflen + CHUNK_SIZE);
req->buflen += CHUNK_SIZE;
}
memcpy(&req->buffer[req->len], ptr, realsize);
req->len += realsize;
req->buffer[req->len] = 0;
return realsize;
}
int main(int argc, char **argv) {
CURL *curl;
CURLcode res;
curl = curl_easy_init();
get_request req = {.buffer = NULL, .len = 0, .buflen = 0};
if (curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "length: 20");
headers = curl_slist_append(headers, "numbers: true");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
req.buffer = malloc(CHUNK_SIZE);
req.buflen = CHUNK_SIZE;
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&req);
res = curl_easy_perform(curl);
printf("Result = %un",res);
printf("Total received bytes: %zun", req.len);
printf("Received data:/n%sn", req.buffer);
free(req.buffer);
}
curl_easy_cleanup(curl);
}
输出:
receive chunk of 1256 bytes
Result = 0
Total received bytes: 1256
Received data:
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
GET 请求完成后,您可以访问req->buffer
中的数据并解析 JSON 对象或任何其他数据。 需要添加错误检查(用于realloc
等(。
我使用了一种能够在接收的任意数量的块中处理任何长度的内容的方法。 如果您知道预期内容的长度,则可以使用固定大小的缓冲区。
正如您在我的例子中看到的,下载完成后用户数据结构仍然存在,并且在curl_easy_perform
返回后可以派生内容。