这里使用了httplib.h,是直接使用的别人封装好的库,超简单搭建服务器和客户端,这只是我自己在工作用的一个demo,内容有点凌乱
服务端
#include "httplib.h"
#include "json.hpp"
#include <iostream>
#include <thread>
using namespace std;
using namespace httplib;
struct test
{
string name;
int age;
};
std::string dump_headers(const Headers &headers)
{
std::string s;
char buf[BUFSIZ];
for (auto it = headers.begin(); it != headers.end(); ++it)
{
const auto &x = *it;
snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());
s += buf;
}
return s;
}
std::string log(const Request &req, const Response &res)
{
std::string s;
char buf[BUFSIZ];
s += "================================\n";
snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(),
req.version.c_str(), req.path.c_str());
s += buf;
std::string query;
for (auto it = req.params.begin(); it != req.params.end(); ++it)
{
const auto &x = *it;
snprintf(buf, sizeof(buf), "%c%s=%s",
(it == req.params.begin()) ? '?' : '&', x.first.c_str(),
x.second.c_str());
query += buf;
}
snprintf(buf, sizeof(buf), "%s\n", query.c_str());
s += buf;
s += dump_headers(req.headers);
s += "--------------------------------\n";
snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str());
s += buf;
s += dump_headers(res.headers);
s += "\n";
if (!res.body.empty())
{
s += res.body;
}
s += "\n";
return s;
}
void s2()
{
sleep(2);
httplib::Client cli("localhost", 8080);
auto ree = cli.Get("/hello");
}
void hi(const httplib::Request &req, httplib::Response &res)
{
nlohmann::json req_j;
req_j = nlohmann::json{
{"streamId", 0000}};
auto body = req_j.dump();
res.set_content(body, "application/json");
thread t1(s2);
t1.detach();
};
void from_json(const nlohmann::json &j, test &t)
{
t.name = j.value("name", "");
t.age = stoi(j.value("age", "0"));
}
void hello(const httplib::Request &req, httplib::Response &res)
{
// httplib::Client cli("localhost", 8080);
// auto ree = cli.Get("/hello");
// if (auto res = cli.Get("/hello")) {
// cout << res << endl;
// cout << res->get_header_value("Content-Type") << endl;
// cout << res->body << endl;
// }
// res.set_content(ree->body + "sss", "application/json");
nlohmann::json req_j;
req_j = nlohmann::json{
{"streamId", 1111}};
auto body = req_j.dump();
res.set_content(body, "application/json");
req_j = nlohmann::json{
{"streamId", 2222}};
body = req_j.dump();
res.set_content(body, "application/json");
}
void test1(const httplib::Request &req, httplib::Response &res)
{
nlohmann::json req_j;
test t;
// for (auto &it : req.params)
// {
// std::cout << "key:" << it.first << " value:" << it.second << std::endl;
// }
//std::map<std::string, int> c_map{{"one", 1}, {"two", 2}, {"three", 3}};
try
{
nlohmann::json js(req.params);
// nlohmann::json j = nlohmann::json::parse(js);
js.get_to(t);
req_j = nlohmann::json{
{"name", t.name}, {"age", t.age}, {"test", "张三"}};
}
catch (nlohmann::json::parse_error &e)
{
req_j = nlohmann::json{
{"msg", "JSON解析失败"},
{"result", 1},
{"streamId", 0},
};
}
auto body = req_j.dump();
res.set_content(body, "application/json");
}
int main(void)
{
Server svr;
svr.Get("/hi", [](const Request &req, Response &res)
{ hi(req, res); });
svr.Get("/hello", [](const Request &req, Response &res)
{ hello(req, res); });
svr.Get("/test1", [](const Request &req, Response &res)
{ test1(req, res); });
svr.set_logger([](const Request &req, const Response &res)
{ printf("%s", log(req, res).c_str()); });
svr.listen("172.16.4.45", 8080);
}
客户端
//
// client.cc
//
// Copyright (c) 2019 Yuji Hirose. All rights reserved.
// MIT License
//
#include "httplib.h"
#include <iostream>
#include "json.hpp"
#define CA_CERT_FILE "./ca-bundle.crt"
using namespace std;
nlohmann::json req_j = nlohmann::json{
{"name", "王五"},
{"age", 69},
};
struct test
{
string name;
int age;
};
void from_json(const nlohmann::json &j, test &t)
{
t.name = j.value("name", "");
t.age = j.value("age", 0);
};
int main(void)
{
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
httplib::SSLClient cli("localhost", 8080);
// httplib::SSLClient cli("google.com");
// httplib::SSLClient cli("www.youtube.com");
cli.set_ca_cert_path(CA_CERT_FILE);
cli.enable_server_certificate_verification(true);
#else
httplib::Client cli("172.16.4.45", 8080);
#endif
test t;
req_j.get_to(t);
string str = "/test1?name=" + t.name + "&age=" + to_string(t.age);
cout << str << endl;
cout << str.data() << endl;
if (auto res = cli.Get(str.data()))
{
cout << res << endl;
cout << res->get_header_value("Content-Type") << endl;
cout << res->body << endl;
}
else
{
cout << "error code: " << res.error() << std::endl;
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
auto result = cli.get_openssl_verify_result();
if (result)
{
cout << "verify error: " << X509_verify_cert_error_string(result) << endl;
}
#endif
}
return 0;
}
其中还搭配使用了json库,客户端只访问了/test1接口,linux下添加了头文件可以直接编译,使用,
g++ server.cpp -o server -std=c++11 -lpthread
g++ client.cpp -o client -std=c++11 -lpthread
httplib.h库链接:GitHub - yhirose/cpp-httplib: A C++ header-only HTTP/HTTPS server and client library
json.hpp库链接:JSON for Modern C++ - 简书