(超简单)cpp-httplib搭建服务器和客户端

  • Post author:
  • Post category:其他


这里使用了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++ – 简书



版权声明:本文为xue_wu_zhi_jing原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。