cpp-httplib是一个c++封装的http开源库,仅包含一个头文件,不过代码行数达到8000多行,相比于上一节中讲述的Tinyhttpd ,该库功能就比较完善,并且可以在简单的项目中使用。

         cpp-httplib 服务端采用select IO多路复用模型,工作线程池的处理方式,主要包含的类Server、Client、Request、Response。

1  简单举例

  1.1 服务端举例

    httplib::Server server;
    auto hello = [](const httplib::Request & req, httplib::Response & rsp) {
        rsp.status = 200;
        rsp.set_content("<html><h1> hello cpp-httplib!</h1></html>", "text/html");
    };
    server.Get("/", hello);
    server.listen("0.0.0.0", 9000);

 1.2 客户端举例

    httplib::Client client("127.0.0.1", 9000);
    auto result = client.Get("/");
    std::cout << result->status << std::endl;
    std::cout << result->body << std::endl;

 上述进行简单的举例,方便掌握处理流程。借助该库还可以实现http推送功能,更多应用可以参考库中自带的例子。

2  整体流程分析

  2.1 服务端Server 分析

 图中描述了整体流程,基本包含了服务端的主要处理步骤。 

a  搭建tcp服务,注册资源路径与处理方法,并开启监听。

b  创建工作线程,select循环监听,当收到客户端消息,放入jobs中,通知工作线程处理。

c  工作线程从jobs中取出待处理请求。

d  处理请求,包含校验、协议解析、根据请求方式分发,最终调用用户注册方法处理上层业务。

2.2 客户端Client 分析

     

 

  

客户端借助类ClientImpl,完成socket初始化,请求下发与解析响应。 

2.3  辅助类 Request、Response

struct Request {
    std::string method;    //请求方式
    std::string path;         //资源路径
    Headers headers;     //请求头属性,键值对方式
    std::string body;        //请求体

}

struct Response {
    std::string version;   //响应版本

    int status;                 //响应状态
    Headers headers;    //响应头
    std::string body;       //响应体

}

Request、Response 分别用来组装HTTP消息请求体与消息响应体 ,HTTP结构可参考如下:

3  测试

     增加了日志打印,配置两个工作线程,从日志可以看出主线程[48280]循环select监听,两个工作线程处理客户端请求。

附:

1 自定义日志接口:可显示时间以及线程id。

#include <stdio.h>
#include <time.h>
#include <thread>
#include <iostream>

template <typename... Args>
void print_log(const char* fmt, Args... args) {
    char log_buf[4096] = { 0 };
    snprintf(log_buf, 4096, fmt, args...);

    time_t time_data = time(NULL);
    tm cur_time;
    localtime_s(&cur_time, &time_data);
    char time_buf[64] = { 0 };
    snprintf(time_buf, 64, "%02d:%02d:%02d",
             cur_time.tm_hour,
             cur_time.tm_min,
             cur_time.tm_sec);

    int  tid = (*(int*)&std::this_thread::get_id());
    char buf[5120] = { 0 };
    snprintf(buf, 5120, "[%s] [%d] [%s]", time_buf, tid, log_buf);
    std::cout << buf << std::endl;
}

2  源码路径 

https://github.com/yhirose/cpp-httplibhttps://github.com/yhirose/cpp-httplib

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐