良许Linux教程网 干货合集 图解丨在嵌入式设备上实现HTTP服务器

图解丨在嵌入式设备上实现HTTP服务器

本期为大家带来一个 WiFi 应用的实际场景,其实在之前「我对 WiFi 驱动移植过程,做了一次总结复盘」这篇文章中有简单提过,但由于内容较多,就单独摘出来了。

来自读者的催更😭😭😭,别着急,小二在努力了!

image-20240126195610658
image-20240126195610658

深度伪原创版本:

1 应用场景

让我们首先讨论一下应用场景,了解它的用途是非常重要的,只有知道在哪里使用以及如何使用,才能编写出优秀的代码嘛,哈哈😉

对于这个项目,实际的应用场景是:通过手机应用程序连接到设备的WiFi热点,进行设备参数的配置;

接下来,结合实际框架,我们将拆分需求如下:

  • 使用HTTP协议,并采用POST方法;
  • 设备端需要作为一个HTTP服务器;
  • 不需要支持CGI,只需要通过应用程序展示界面即可;

现在我们已经清楚了需求,接下来就是制定实施方案。

2 方案论证

一开始,我们毫无头绪。

组长提供的一种方案是在新唐(NXP)的数据手册中找到的,使用Lighttpd方案。

后来我查阅了一些资料,发现了一篇介绍不同HTTP服务器的文章,非常不错,链接如下:

常见的几种嵌入式web服务器(https://www.cnblogs.com/quliuliu2013/p/12786301.html)

2.1 Lighttpd

最初,我的同事开始研究这个方案,但后来我提出了我们团队的需求,开始思考是否可以采用这个方案。

毕竟这个方案已经成型,可以节省不少时间。

后来经过分析,我发现Lighttpd需要一个独立的进程来执行,如下图所示:

640
640

Lighttpd 提供了 CGI 接口,支持 IE 访问固定界面,然后进行参数配置。

实际实现方案,我认为比较好的方法是,Lighttpd 进程接收到参数变更时,写入配置文件 A ,主业务进程监测文件 A 是否有改变,如果检测到改变,则读一次数据。

具体实现方式,参考下图

640 (1)
640 (1)

结合实际情况分析,

1、目前只维护一个主业务进程,如果再增加额外的进程,则维护成本将大大增加。

2、实际不需要 CGI 接口,不需要支持 IE ,APP 做界面显示即可。

经过论证,此方案较复杂,暂且当做最后的备选方案。

2.2 cpp-httplib

接着我就去 GitHub 上寻找 HTTP Server ,发现 cpp-httplib 这个比较好用的库。

GitHub 链接:cpp-httplib(https://github.com/yhirose/cpp-httplib)

在查看了 ReadMe 文件后,很遗憾,我用不了😑😑😑

提示说 GCC 4.8 及以下版本无法正常编译,因为 文件已损坏。。。

image-20240126195641162
image-20240126195641162

我去找了找解决方法,发现在 GCC 4.9 版本修复了这个问题,参考 Stack Overflow 回答如下

https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions

没办法了,我们当前 GCC 版本是 4.8.3 的,肯定不能因为这个库就更换编译器呀,那只能再去找找看咯。

2.3 httpserver

然后就接着去搜索,发现了 httpserver 这个库,只有一个 .h 头文件,感觉很简单。

GitHub 链接:httpserver(https://github.com/jeremycw/httpserver.h)

分析本质需求,发现只需要在主进程中,跑一个 HTTP Server 的线程,监听固定端口,然后采用 HTTP 协议进行通信即可。

简要功能,如下图所示

640 (2)
640 (2)

从上图可以看出

1、主进程中,单独跑一个 HTTP Server 的线程,监听固定端口 8888 ;

2、此线程同时进行数据处理,将参数写入文件 A ;

3、其他业务线程,在需要参数时,直接去文件 A 获取最新参数即可;

3 实现方式

具体实现方式,参考 ReadMe 文件,也很方便实现。

简述一下主要流程:

  • 绑定监听端口号,绑定回调函数;
  • 死循环监听端口;
  • 当需要关闭 HTTP 服务时,通过 flag 标志位,改变当前状态;
  • 关闭 HTTP 服务后,需要释放相应资源;
  • 所有的配置处理接口,在 HandleRequest 回调函数中;

(PS:我这电脑网络有问题,GitHub 一直打不开,手机热点也不行,暂时还没别的好办法,只能麻烦您自己去网页上看啦。)

4 注意事项

在使用过程中,我这遇到一个问题。

您看下边这块代码,是这样的

void hs_init_session(http_request_t* session) {
  session->flags = HTTP_AUTOMATIC;
  session->parser = (http_parser_t){};
  session->stream = (hs_stream_t){};
  if (session->tokens.buf) {
    free(session->tokens.buf);
    session->tokens.buf = NULL;
  }
  http_token_dyn_init(&session->tokens, 32);
}

在第 3 、4 行末尾,直接就是一个大括号,里边什么都没写。

然后我的程序在这个地方就一直编译不过去。后来在公司前辈指点下,按照下图所示,添加了 0 之后,就能编译通过了。

推测原因是当前编译器使用的 C 标准,不支持这么高级的用法。

image-20240126195657861
image-20240126195657861

注意:需要修改的不止这一处,其他地方如有编译报错,也需做类似修改。

5 总结

针对本次的功能需求,最困难的地方,在于寻找一个合适的 HTTP Serve 库来使用。

过程虽然艰难,但也锻炼了自己找东西的能力。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部