接上一篇文章:libcurl 配合 jsoncpp 向 http 服務器發送 post 請求,在上一篇文章中我向 web 服務器使用 post 模擬表單的方式發送了一個請求接收了響應數據。
$./test
* Trying 192.168.7.6...
* Connected to 192.168.7.6 (192.168.7.6) port 9999 (#0)
> POST /v1/annotation/face-detect HTTP/1.1
Host: 192.168.7.6:9999
User-Agent: Agent
Accept: */*
Content-Length: 95
Content-Type: application/x-www-form-urlencoded
* upload completely sent off: 95 out of 95 bytes
< HTTP/1.1 200 OK
< Server: openresty/1.15.8.2
< Date: Thu, 14 Nov 2019 09:13:50 GMT
< Content-Type: application/json
< Content-Length: 343
< Connection: keep-alive
<
* Connection #0 to host 192.168.7.6 left intact
從 http 的響應頭字段:Content-Type: application/json可知服務器響應了我們一個 json 字符串數據,如下:
{
"data": [
{
"annotation": [
[
"c", //類別
1.0, //confidence
[
256, //x0
238, //y0
237, //w
266 //h
]
]
],
"file": "/home/kaas/kaas/kaas_server/tests/image/face_detect/_300VW-3D_CatA_114_2141.jpg"
}
],
"msg": "success",
"status": 0
}
下面我們使用 jsoncpp 來解析上面這個比較複雜的 json 字符串結構,我在上一篇的代碼中加了一個 parse 函數專門來解析這個 json 串。
#include <iostream>
#include <curl/curl.h>
#include <sstream> //std::stringstream
#include "json/json.h"
/*
處理接收數據處理的回調函數,在這裏我將接收到的數據寫入到數據存放變量(stream)中
*/
static size_t func_write_data(void *ptr, size_t size, size_t nmemb, void *stream) {
std::string data((const char*) ptr, (size_t) size * nmemb);
*((std::stringstream*) stream) << data << std::endl;
return size * nmemb;
}
void parse(const std::string out) {
Json::Reader jr(Json::Features::strictMode());
Json::Value jv;
if (jr.parse(out.c_str(), jv)) {
int status = jv.get("status",0).asInt();
std::cout << "status: " << status << std::endl;
std::string msg = jv.get("msg",0).asString();
std::cout << "msg: " << msg << std::endl;
Json::Value data = jv.get("data",0);
int sz = data.size();
std::cout << "data length: " << sz << std::endl;
for (int i=0; i<sz; i++) {
Json::Value data_i = data[i];
std::cout << "i: " << i << ", file: " <<
data_i.get("file",0).asString();
Json::Value anno = data_i.get("annotation",0);
int anno_size = anno.size();
for (int j=0; j<anno_size; j++) {
std::cout << "name: " << anno[j][0] << std::endl;
std::cout << "score: " << anno[j][1] << std::endl;
Json::Value box = anno[j][2];
int box_size = box.size();
std::cout << "box_length: " << box_size << std::endl;
for (int k=0; k<box_size; k++) {
std::cout << "box " << k << " :" << box[k] << std::endl;
}
}
}
}
}
int main(int argc, char* argv[]) {
/*
請求參數格式
{
'files':[
"${filepath}"
]
}
*/
//json 封裝
std::string path="/home/kaas/kaas/kaas_server/tests/image/face_detect/_300VW-3D_CatA_114_2141.jpg";
Json::Value files;
files.append(path);
std::string request = "files=" + files.toStyledString();
std::stringstream resp; // 請求響應
std::string url = "http://192.168.7.6:9999/v1/annotation/face-detect";
//初始化curl
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cout << "init curl error" << std::endl;
return -1;
}
//struct curl_slist* header_list = NULL; //need free
//header_list = curl_slist_append(header_list, "Content-Type:application/x-www-form-urlencoded");
//curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3000);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Agent");
curl_easy_setopt(curl, CURLOPT_POST, 1); //設置請求方式爲 post
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.c_str()); //加載 post 數據
//設置接收數據的回調函數以及存放數據的變量
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, func_write_data);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); //訪選項可以獲取請求詳情
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); //設置請求 url,必不可少
CURLcode ret = CURLE_OK;
ret = curl_easy_perform(curl); //執行請求
if (CURLE_OK != ret) {
std::cout << "execute error: " << ret << std::endl;
return -1;
}
//輸出響應結果
std::cout << resp.str();
std::cout << "--------------------" << std::endl;
//解析響應結果
parse(resp.str());
curl_easy_cleanup(curl); //釋放資源
curl_global_cleanup();
return 0;
}
編譯,運行一下:
[localhost ~]$ cat build.sh
g++ test.cpp -o test -lcurl libjsoncpp.a -Iinclude
[localhost ~]$ ./test
{
"data": [
{
"annotation": [
[
"c",
1.0,
[
256,
238,
237,
266
]
]
],
"file": "/home/kaas/kaas/kaas_server/tests/image/face_detect/_300VW-3D_CatA_114_2141.jpg"
}
],
"msg": "success",
"status": 0
}
--------------------
status: 0
msg: success
data length: 1
i: 0, file: /home/kaas/kaas/kaas_server/tests/image/face_detect/_300VW-3D_CatA_114_2141.jpgname: "c"
score: 1
box_length: 4
box 0 :256
box 1 :238
box 2 :237
box 3 :266
ok,就這樣了!!!