查看: 2329|回复: 20

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

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3299

    主题

    6546

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32023
    最后登录
    2024-4-25
    发表于 2021-6-25 14:25:19 | 显示全部楼层 |阅读模式
    图解丨在嵌入式设备上实现HTTP服务器


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

    1 应用场景
    我喜欢讲一个东西,先来探讨下他的应用场景。
    毕竟知道了用在哪,怎么用,才能写好代码嘛,哈哈

    本次项目,实际的应用场景:通过手机 APP ,连接到设备 WiFi 热点,进行设备的参数配置;

    接着结合实际框架,拆分需求如下:

    采用 HTTP 协议,使用 POST 方法;
    设备端需要作为一个 HTTP 服务器;
    不需要支持 CGI ,通过 APP 展示界面即可;
    好了,明白了需求,接下来就是实现方案了。

    2 方案论证
    刚开始的时候,一点头绪都没有。
    组长指导的一种方案,就是在新唐数据手册中看到的,采用 Lighttpd 的方案。
    后来去查资料,发现一篇介绍不同 HTTP 服务器的文章,挺不错的,如下
    常见的几种嵌入式web服务器(https://www.cnblogs.com/quliuliu2013/p/12786301.html

    2.1 Lighttpd
    这块刚开始是同事在搞,后来我这边的需求规划出来后,就在想能否使用这种方案。
    毕竟方案是现成的,可以节省不少时间。

    后来经过分析,发现 Lighttpd 需要一个单独的进程执行,如下图所示
    21.png

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

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

    具体实现方式,参考下图
    22.png

    结合实际情况分析,

    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 及以下版本无法正常编译,因为 <regex> 文件已损坏。。。
    23.png

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

    https://stackoverflow.com/questi ... regular-expressions

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

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

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

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

    简要功能,如下图所示
    24.png

    从上图可以看出

    1、主进程中,单独跑一个 HTTP Server 的线程,监听固定端口 8888 ;
    2、此线程同时进行数据处理,将参数写入文件 A ;
    3、其他业务线程,在需要参数时,直接去文件 A 获取最新参数即可;

    3 实现方式
    具体实现方式,参考 ReadMe 文件,也很方便实现。
    简述一下主要流程:
    绑定监听端口号,绑定回调函数;
    死循环监听端口;
    当需要关闭 HTTP 服务时,通过 flag 标志位,改变当前状态;
    关闭 HTTP 服务后,需要释放相应资源;
    所有的配置处理接口,在 HandleRequest 回调函数中;
    (PS:我这电脑网络有问题,GitHub 一直打不开,手机热点也不行,暂时还没别的好办法,只能麻烦您自己去网页上看啦。)

    4 注意事项
    在使用过程中,我这遇到一个问题。

    您看下边这块代码,是这样的
    1. void hs_init_session(http_request_t* session) {
    2.   session->flags = HTTP_AUTOMATIC;
    3.   session->parser = (http_parser_t){};
    4.   session->stream = (hs_stream_t){};
    5.   if (session->tokens.buf) {
    6.     free(session->tokens.buf);
    7.     session->tokens.buf = NULL;
    8.   }
    9.   http_token_dyn_init(&session->tokens, 32);
    10. }
    复制代码
    在第 3 、4 行末尾,直接就是一个大括号,里边什么都没写。

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

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

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

    5 总结
    针对本次的功能需求,最困难的地方,在于寻找一个合适的 HTTP Serve 库来使用。
    过程虽然艰难,但也锻炼了自己找东西的能力。
    好了各位看官,本次的分享到此结束,如果您还意犹未尽,大可从头再看。




    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2021-6-25 15:31:11 | 显示全部楼层
    我对嵌入式设备连接wifi网络还是有些不同意见的。
    我觉得网关连接wifi,其余终端通过其它方式与网关交互,而由网关最终将数据上云
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3299

    主题

    6546

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32023
    最后登录
    2024-4-25
     楼主| 发表于 2021-6-25 15:53:22 | 显示全部楼层
    jobszheng5 发表于 2021-6-25 15:31
    我对嵌入式设备连接wifi网络还是有些不同意见的。
    我觉得网关连接wifi,其余终端通过其它方式与网关交互, ...

    文章刚出了点问题,我修改了一下
    签到签到
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2021-6-25 16:14:04 | 显示全部楼层
    NXP管管 发表于 2021-6-25 15:53
    文章刚出了点问题,我修改了一下

    这个思路与技术是没有问题的。
    完全可以实现

    我也是谈了一下我的想法。——其实,我自己也挺犹豫这个想法的
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-12-25 08:42
  • 签到天数: 391 天

    [LV.9]以坛为家II

    45

    主题

    1337

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    3156
    最后登录
    2024-2-19
    发表于 2021-6-25 16:41:14 | 显示全部楼层
    单片机的数据处理能力还是偏弱
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    4 小时前
  • 签到天数: 1939 天

    [LV.Master]伴坛终老

    61

    主题

    1万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    17288
    最后登录
    2024-4-25
    发表于 2021-6-25 21:46:09 | 显示全部楼层
    jobszheng5 发表于 2021-6-25 15:31
    我对嵌入式设备连接wifi网络还是有些不同意见的。
    我觉得网关连接wifi,其余终端通过其它方式与网关交互, ...

    这个样就对网关的性能要求高了。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    4 小时前
  • 签到天数: 1939 天

    [LV.Master]伴坛终老

    61

    主题

    1万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    17288
    最后登录
    2024-4-25
    发表于 2021-6-25 21:50:20 | 显示全部楼层
    jobszheng5 发表于 2021-6-25 15:31
    我对嵌入式设备连接wifi网络还是有些不同意见的。
    我觉得网关连接wifi,其余终端通过其它方式与网关交互, ...

    各有优缺点,可以适用不同场景。有些无线链接对设备个数有限制,可以拿个网关中转,多连接些设备。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    13 小时前
  • 签到天数: 1047 天

    [LV.10]以坛为家III

    0

    主题

    1508

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    4031
    最后登录
    2024-4-24
    发表于 2021-6-26 00:02:32 | 显示全部楼层
    学习下
    酷酷酷哦你很快
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    4 小时前
  • 签到天数: 2001 天

    [LV.Master]伴坛终老

    23

    主题

    6170

    帖子

    21

    金牌会员

    Rank: 6Rank: 6

    积分
    11921
    最后登录
    2024-4-25
    发表于 2021-6-26 09:08:52 | 显示全部楼层
    关注下!
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-12-30 08:07
  • 签到天数: 87 天

    [LV.6]常住居民II

    0

    主题

    242

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    1097
    最后登录
    2022-12-30
    发表于 2021-6-26 11:48:54 | 显示全部楼层
    参与收藏然后提示任务不成功
    生命不息,奋斗不止!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-25 13:52 , Processed in 0.163721 second(s), 31 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表