前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Libmicrohttpd嵌入式服务

Libmicrohttpd嵌入式服务

作者头像
随心助手
发布2019-10-15 11:23:20
1.3K0
发布2019-10-15 11:23:20
举报

Libmicrohttpd简介

GNU Libmicrohttpd是一个用来在项目中内嵌http服务器的C语言库,它具有以下几个非常鲜明的特点:

  1. C语言库,小而快。
  2. API非常简单,且都是可重入的。
  3. 兼容HTTP1.1。
  4. 支持4种多线程模型(select、poll、pthread、thread poll)。
  5. 跨平台。
  6. 生成的二制文件只有32K(不包含TLS/SSL等额外功能)。

搭建一个简单的本地静态服务器

这篇文章里,我们只编写一个简单的静态服务器,对于用户的所有请求我们都只返回同一个html页面, 该页面显示一串字符。

1. 下载Libmicrohttpd,编译后添加进VS项目

为了使用Libmicrohttpd,我们需要将其添加进VS项目中。这里我们选择编译源代码生成静态库,因为官方给的下载静态库版本链接在使用时会有问题,可能是运行库版本不一致; 并且在使用静态库的情况下,我们只需要引用两个文件就可以了(一个头文件、一个库文件),项目结构不会混乱不清。

实际上Libmicrohttpd的源码编译非常简单,它提供了VS编译文件,基本上我们只需要进入w32目录,在该目录下选择合适的VS子目录下的sln文件,双击打开就可以了。打开后,修改设置libmicrohttpd项目为静态库项目(记得修改生成文件的后缀名,因为默认是dll),右击生成就可以编译成功了。

生成的文件包括一个头文件和一个静态库文件,新建一个VS控制台项目,并将它们添加到VS项目中。

2. main函数

main函数非常简单,核心调用只有2个函数:MHD_start_daemonMHD_stop_daemon,分别开始和停止http服务器。

int main()
{
    const int port = 8888;

    struct MHD_Daemon* daemon = 
        MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port
        , NULL, NULL, connectionHandler, NULL, MHD_OPTION_END);
    if (daemon == NULL) {
        std::cout << "cannot start server!\n";
        return -1;
    }

    std::cin.get();
    MHD_stop_daemon(daemon);
    return 0;
}

MHD_start_daemon函数包含非常多的参数,这也意味着它集成了很多的功能,这里我们只关注四个参数,其它都为NULL:

  1. MHD_USE_INTERNAL_POLLING_THREAD。这个参数与其他两个参数(MHD_USE_POLL_INTERNAL_THREAD、MHD_USE_EPOLL_INTERNAL_THREAD)一起构成了microhttpd支持的三种模式:select、poll、epoll。用户必须选择这三种模式之一。具体信息见源码。
  2. port。端口号。
  3. connectHandler。处理请求的函数。
  4. MHD_OPTION_END。由于MHD_start_daemon最后一个参数是一个变参,因此MHD_OPTION_END用来表示变参终止。

MHD_stop_daemon函数比较简单,这里不介绍了。

3 请求处理函数

所有的请求处理都发生在connectionHandler中:

int  connectionHandler(
    void *cls,
    struct MHD_Connection *connection,
    const char *url,
    const char *method,
    const char *version,
    const char *upload_data,
    size_t *upload_data_size,
    void **con_cls)
{
    const char* pageBuffer = "<html><body>Hello, I'm lgxZJ!</body></html>";

    struct MHD_Response *response;
    response = MHD_create_response_from_buffer(strlen(pageBuffer),
        (void*)pageBuffer, MHD_RESPMEM_PERSISTENT);

    if (MHD_add_response_header(response, "Content-Type", "text/html") == MHD_NO) {
        std::cout << "MHD_add_response_header error\n";
        return MHD_NO;
    }
    if (MHD_queue_response(connection, MHD_HTTP_OK, response) == MHD_NO) {
        std::cout << "MHD_queue_response error\n";
        return MHD_NO;
    }
    MHD_destroy_response(response);

    return MHD_YES;
}

这个函数签名包含了所有用来处理请求的有用信息,这里不逐一介绍了。microhttpd库提供了函数来方便我们响应请求,这里我们重点看创建响应。microhttpd库提供了两种方法来创建请求:从buffer创建从文件创建。但是后者需要传入一个文件描述符,这在windows上不是很方便。

我们这里用缓冲创建。需要注意的是最后一个参数,这是一个MHD_ResponseMemoryMode枚举值,表示我们使用的buffer内容是固定不变的。这种枚举类型还包含其他2种代表瞬时缓冲类型的值,分别表示缓冲区是在heap上的,和非heap(例如stack)上的。 用不同的缓冲区时要记得用不同的枚举值。 接下来设置MIME类型,把缓冲入队,并释放MHD_Response结构体。对于正确响应,我们返回MHD_YES;不能响应的,我们返回MHD_NO。

运行程序,我们打开浏览器并输入127.0.0.1:8888,得到如下结果:

还能做更多

  • MHD_start_daemon函数还可以限制特定ip的访问。
  • 请求处理函数还包含请求方法请求数据
  • 我们还可以挂起、恢复连接
  • ......
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nginx遇上redis 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Libmicrohttpd简介
  • 搭建一个简单的本地静态服务器
    • 1. 下载Libmicrohttpd,编译后添加进VS项目
      • 2. main函数
        • 3 请求处理函数
        • 还能做更多
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档