libcur(c语言)
libcurl是一个跨平台的网络协议库,支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, HTTP基本表单上传,代理,cookies,和用户认证
libcurl的官网 http://curl.haxx.se/
libcur官网有丰富的文档和例子,稳定库。
详细内容自己可以查阅
http协议
libcurl是实现了http协议,只需要简单使用即可
typedef map<string, string> curlMap;
struct memory {
char* response;
size_t size;
};
int httpRequest(curlMap map)
{
//组合参数
string req;
curlMap::iterator it;
for (it = map.begin(); it != map.end(); it++)
{
req.append(it->first);
req.append("=");
req.append(it->second);
req.append("&");
}
if (req.size() > 0 && req[req.size() - 1] == '&')
{
//清理最后一个字符&
req.erase(req.size() - 1);
}
CURL* curl;
CURLcode res;
//初始化协议
curl_global_init(CURL_GLOBAL_ALL);
//创建句柄
curl = curl_easy_init();
if (curl) {
//初始化接收
struct memory chunk = { 0 };
//创建连接,这里是restfull方式
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8081/curlreq");
//设置回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
//设置用户数据读取
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
//如果有参数,则按照post方式传输
if (req.size() > 0)
{
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req);
}
//curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
//传输数据并且返回
res = curl_easy_perform(curl);
//检查错误
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
//清理连接,释放内存
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
size_t write_data(void* data, size_t size, size_t nmemb, void* userp)
{
size_t realsize = size * nmemb;
struct memory* mem = (struct memory*)userp;
void* curMem = mem->response;
int cursize = mem->size + realsize + 1;
char* ptr = (char*)realloc(curMem, cursize);
if (ptr == NULL)
return 0; /* out of memory! */
mem->response = ptr;
memcpy(&(mem->response[mem->size]), data, realsize);
mem->size += realsize;
mem->response[mem->size] = 0;
string result(mem->response, mem->size);
std::cout << result << endl;
return realsize;
}
配合使用
json字符串使用接收
如果只是解析json字符串,则c++的jsoncpp库方便解析,并且简单
int ParseJsonFromString()
{
const char* str = "{\"uploadid\": \"UP000000\",\"code\": 100,\"msg\": \"\",\"files\": \"\"}";
Json::Reader reader;
Json::Value root;
if (reader.parse(str, root)) // reader将Json字符串解析到root,root将包含Json里所有子元素
{
std::string upload_id = root["uploadid"].asString(); // 访问节点,upload_id = "UP000000"
int code = root["code"].asInt(); // 访问节点,code = 100
}
return 0;
}
如果需要使用结构体转换字符串,则nlohmann库可以使用简单的功能
int ParseJson()
{
// create object from string literal
json j = "{ \"happy\": true, \"pi\": 3.141 }"_json;
// or even nicer with a raw string literal
auto j2 = R"(
{
"happy": true,
"pi": 3.141
}
)"_json;
std::string s = j.dump();
return 0;
}
更加复杂一点点的
struct MyContainer {
std::string name;
std::string address;
int age;
list<string> lst;
double score;
};
void to_json(nlohmann::json& j, const MyContainer& p) {
j = json{ {"name", p.name}, {"address", p.address}, {"score", p.score},{"age",p.age} };
}
void from_json(const nlohmann::json& j, MyContainer& p) {
j.at("name").get_to(p.name);
j.at("address").get_to(p.address);
j.at("score").get_to(p.score);
j.at("age").get_to(p.age);
}
int defParseJson()
{
MyContainer c;
c.age = 3;
c.name = "jnoy";
c.score = 6;
c.lst.push_back("aa");
c.lst.push_back("cc");
json j = c;//将结构体转换成json对象
std::string str= j.dump();//转换字符串
std::cout << str << std::endl;
//必须在同名称空间,实现to_json,from_json
auto p= j.get<MyContainer>();//转换结构体
// json k = c;
return 0;
}
这样就可以实现restfull方式访问。