良许Linux教程网 干货合集 简单易用的嵌入式网络库:Mongoose

简单易用的嵌入式网络库:Mongoose

Mongoose 是什么?

Mongoose 是一个非常方便易用的网络库,适用于各种应用场景。

该库提供了基于事件驱动的非阻塞 API,可用于实现 TCP、UDP、HTTP、WebSocket 和 MQTT 等网络协议。特别适合在嵌入式系统中使用。

如果你想了解更多关于 Mongoose 的信息:

在官网上,列举了 Mongoose 的许多优点,其中我个人认为以下几点是最值得注意的:

  1. Mongoose 以其简洁的代码结构著称,只有一个 mongoose.c 文件和一个 mongoose.h 文件。
  2. 该库的设计注重减少外部依赖,仅依赖于基础的 Socket 编程,没有引入第三方库。
  3. 经过广泛使用和验证,Mongoose 是一个非常稳定可靠的库。Github 上有超过 8.1K 的 Star,许多知名企业都以 Mongoose 为基础推出了商业产品。
  4. Mongoose 提供了丰富的文档和示例代码,帮助开发者更好地理解和使用该库。

Mongoose 怎么用?

Mongoose 解决了广泛的业务需求,如在设备上实现 Web UI 界面、RESTful API 服务、遥测数据交换、产品远程控制、远程软件更新、远程监控等。

下面是官方提供的示例

image-20240101190302460
image-20240101190302460

点击查看大图

我们简单地看点代码。

示例1:实现 HTTP server

// main.c 
#include "mongoose.h"

static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
  // Serve local dir
  struct mg_http_serve_opts opts = {.root_dir = "."};
  if (ev == MG_EV_HTTP_MSG) mg_http_serve_dir(c, ev_data, &opts);
}

int main(int argc, char *argv[]) {
  struct mg_mgr mgr;
  mg_mgr_init(&mgr);
  // Setup listener
  mg_http_listen(&mgr, "http://localhost:8000", fn, &mgr);
  // Event loop
  for (;;) mg_mgr_poll(&mgr, 1000);
  mg_mgr_free(&mgr);
  return 0;
}

将上面的 main.c 和 mongoose.c 一起编译,就可以得到一个最简单的 HTTP server了,它会列举 server 当前所在目录下的文件列表。

对于源码,mg_http_listen() 负责建立 http server,然后 mg_mgr_poll() 负责等待事件的发生。

示例2:swupdate

swupdate 是一个关于 嵌入式 Linux OTA 的开源项目。它集成了 Mongoose, 以实现通过 web 来上传更新包的功能。

image-20240101190307570
image-20240101190307570

点击查看大图

具体的代码实现请自行阅读:

https://github.com/sbabic/swupdate/blob/master/mongoose/mongoose_interface.c

Mongoose 是怎么实现的?

想要理解 Mongoose 的核心设计,要抓住 2个要点:

1、如何对 Socket 编程进行封装?

2、如何实现事件驱动?

对此,我们只要重点阅读其源码里的几个核心的 API 和结构体就够了。为了控制篇幅,下面以理解 TCP 通讯的实现为例。

1> struct mg_mgr

struct mg_mgr {
  struct mg_connection *conns; 
  unsigned long nextid; 
};

mg_mgr 负责管理所有的网络连接。

2> struct mg_connection

struct mg_connection {
  struct mg_connection *next;
  // 地址信息
  struct mg_addr loc;
  struct mg_addr rem;
  int fd;
  unsigned long id;
  // 收发的数据
  struct mg_iobuf recv;
  struct mg_iobuf send;
  // 用户定义的事件处理函数
  mg_event_handler_t fn;
  // 预定义的协议专用的事件处理函数
  mg_event_handler_t pfn;
  ...
};

mg_connection 代表一个网络通讯连接,这个结构体可以处理 TCP、UDP、HTTP、WebSocket、MQTT等协议。

3> mg_listen()

示例:

mg_listen(&mgr, "tcp://0 0.0.0.0:1989", fn, NULL);

这个 API 用于建立 TCP Server,它封装了 TCP Socket 编程的所有细节。它的内部实现大致就是创建一个 mg_connection,然后调用 socket()、setsockopt()、bind()、listen()。

与其想对应的是 mg_connect(),它负责发起 TCP 连接,内部实现类似。

4> mg_mgr_poll()

这个 API 会使用 select() 监听所有的 socket。

当有事件发生时,例如有客户连接、数据可读写,调用对应的 mg_connection 的事件处理函数, 执行用户定义的事件处理流程。

到此,Mongoose 对 TCP 通讯的核心封装思路就分析完毕了。

至于其是如何封装 UDP、HTTP、WebSocket、MQTT 等协议的使用,请自行阅读源码。

总结

Mongoose 使嵌入式网络编程变得快速、健壮和简单。

网络编程的水很深,细节很多。

虽说有一本经典书籍《UNIX 网络编程》,但是大多数人根本没时间去阅读这么厚的一本书。

如果你想给你的嵌入式设备增加网络通讯的能力,真的可以考虑集成 Mongoose。

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

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

作者: 良许

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

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

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

微信扫一扫关注我们

关注微博
返回顶部