libmicrohttpd库

libmicrohttpd

libmicrohttpd 是 GUN 下开源的一个小型的 HTTP 库,能够方便的嵌入到系统中。

安装步骤

--disable-messages是关闭MHD的错误日志功能,MHD的错误日志是直接输出到屏幕的
--enable-https开启https支持需要依赖库gnutls

wget https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.63.tar.gz -O libmicrohttpd-0.9.63.tar.gz
tar -xzf libmicrohttpd-0.9.63.tar.gz
cd libmicrohttpd-0.9.63
./configure --enable-shared=no --disable-doc --disable-examples --enable-https=no --disable-messages
sudo make install

线程模式

  • MHD_USE_INTERNAL_POLLING_THREAD:内部线程模式,1个线程管理监听套接字和所有的连接
  • MHD_USE_INTERNAL_POLLING_THREAD并且MHD_USE_THREAD_PER_CONNECTION:MHD创建1个监听线程并为每条连接单独创建1个线程
  • MHD_USE_INTERNAL_POLLING_THREAD并且MHD_OPTION_THREAD_POOL_SIZE的值大于1:创建一个线程池管理所有连接
  • 默认:不创建线程,调用者需自己调用MHD_run函数来运行事件循环

事件循环模式

  • MHD_USE_POLL:使用poll
  • MHD_USE_EPOLL:使用epoll,linux下可以使用
  • MHD_USE_AUTO:自动选择,选择顺序为epoll,poll,selecet

基础示例

#include <iostream>
#include <string>
#include <memory>
#include <cstring>
#include <microhttpd.h>

// 处理http请求的回调函数,当出现了错误要关闭连接返回MHD_NO
int callback(
    void* cls,
    MHD_Connection* connection,
    const char* url,                // 请求url
    const char* method,             // 请求方法(GET,PUT,POST,HEAD,DELETE,CONNECT,OPTIONS,TRACE)
    const char* version,            // http协议版本,目前是HTTP1.1
    const char* upload_data,        // 上传的数据
    size_t* upload_data_size,       // 上传数据的长度,最后需要修改为没有处理的数据的长度
    void** ptr                      // 用来在同一次连接多次调用回调函数中传递数据
) {
    (void)cls;
    (void)upload_data;
    (void)upload_data_size;
    (void)ptr;
    std::cout << "url[" << url << "]" << std::endl;
    std::cout << "method[" << method << "]" << std::endl;
    std::cout << "version[" << version << "]" << std::endl;

    if (0 != strcmp(method, "GET")) {
        // 目前只处理GET请求
        return MHD_NO;
    }

    // 构建回复消息包
    static std::string s_page = "<html><head><title>libmicrohttpd demo</title></head><body>libmicrohttpd demo</body></html>";
    MHD_Response *response = nullptr;
    response = MHD_create_response_from_buffer(
        s_page.size(),
        &s_page[0],
        MHD_RESPMEM_PERSISTENT
    );
    int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
    MHD_destroy_response(response);
    return ret;
}

int main(int argc, char const *argv[])
{
    (void)argc;
    (void)argv;

    uint16_t port = 10086;
    MHD_Daemon* httpd = nullptr;
    httpd = MHD_start_daemon(
        MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,     // 开启标志
        port,                                               // 监听端口号
        nullptr,                                            // 是否允许连接的回调函数
        nullptr,                                            // 上述回调函数的闭包数据
        callback,                                           // 处理http请求的回调函数
        nullptr,                                            // 上述回调函数的闭包数据
        MHD_OPTION_END
    );

    if (nullptr == httpd) {
        std::cout << "error" << std::endl;
        return 1;
    }

    char ch;
    std::cin >> ch;

    MHD_stop_daemon(httpd);

    return 0;
}
posted @ 2020-11-09 13:41  HachikoT  阅读(1428)  评论(0编辑  收藏  举报