cesanta/mongoose

GitHub: cesanta/mongoose

Mongoose 是一个跨平台的嵌入式网络库,为 C/C++ 提供轻量级事件驱动 API,支持 HTTP、WebSocket、MQTT 等多种协议,可运行于裸机、RTOS 和主流操作系统之上。

Stars: 12627 | Forks: 2890

# Mongoose - 嵌入式 Web 服务器 / 嵌入式网络库 [![License: GPLv2/Commercial](https://img.shields.io/badge/License-GPLv2%20or%20Commercial-green.svg)](https://opensource.org/licenses/gpl-2.0.php) [![Build Status]( https://github.com/cesanta/mongoose/actions/workflows/quicktest.yml/badge.svg)](https://github.com/cesanta/mongoose/actions) [![Code Coverage](https://codecov.io/gh/cesanta/mongoose/branch/master/graph/badge.svg)](https://codecov.io/gh/cesanta/mongoose) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/mongoose.svg)](https://issues.oss-fuzz.com/issues?sort=-opened&can=1&q=proj:mongoose) Mongoose 是一个用于 C/C++ 的网络库。它为 TCP、UDP、HTTP、WebSocket、MQTT 和其他协议提供了事件驱动的非阻塞 API。它专为连接设备并将其上线而设计。自 2004 年上市以来,已被大量开源和商业产品使用——它甚至运行在国际空间站上!Mongoose 使嵌入式网络编程变得快速、健壮且简单。功能包括: - 跨平台: - 运行于 Linux/UNIX、MacOS、Windows、Android - 运行于 ST、NXP、ESP32、Nordic、TI、Microchip、Infineon、Renesas 及其他芯片 - 一次编写代码 - 即可在任何地方运行 - 非常适合统一公司内部的网络基础设施代码 - 内置协议:plain TCP/UDP、SNTP、HTTP、MQTT、Websocket 等 - 异步 DNS 解析器 - 极小的静态和运行时占用 - 源代码同时符合 ISO C 和 ISO C++ 标准 - 易于集成:只需将 [mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) 和 [mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h) 文件复制到您的源码树中 - 内置 TCP/IP 协议栈,包含用于裸机或 RTOS 系统的驱动程序 - 可用驱动:STM32F, STM32H; NXP RT1xxx; TI TM4C; Microchip SAME54; Wiznet W5500 - 在裸机 ST Nucleo 开发板上完整的 Web 设备仪表盘仅需 6 个文件 - 相比之下,CubeIDE 生成的 HTTP 示例有 400 多个文件 - 可以运行在现有支持 BSD API 的 TCP/IP 协议栈之上,例如 lwIP、Zephyr、Azure 等 - 内置 TLS 1.3 ECC 协议栈。也可以使用外部 TLS 库 - mbedTLS、OpenSSL 或其他 - 实现网络功能不依赖任何其他软件 - 针对 STM32 H5、STM32 H7 的内置固件更新 完整文档、视频、案例研究等请参阅 https://mongoose.ws/。 ## 支持的平台 Mongoose 可以在任何支持 BSD socket API 的 TCP/IP 协议栈之上运行。 第三方 TCP/IP 协议栈支持的平台: | TCP/IP stack | Notes | | :-------------- | :------- | | **lwIP** | 所有运行 lwIP 的设备,例如 ESP32, ESP32S3, ESP32C3, ESP32C6 等 | | **Zephyr** | Zephyr 支持的所有设备 | | **Other** | 任何其他支持 BSD socket API 的 TCP/IP 协议栈,例如 Amazon FreeRTOS-TCP | | **Linux, Mac, Windows** | 工作站、服务器、单板计算机、运行在 MPU 或 FPGA 上的嵌入式 Linux 设备 | 可选地,Mongoose 提供了自己内置的 TCP/IP 协议栈,无需额外软件即可实现网络功能。内置协议栈支持在裸机和 RTOS 环境中运行。 Mongoose 内置 TCP/IP 协议栈支持的平台: | Hardware | Notes | | :------------- | :------- | | **STM32** | 所有内置以太网的 STM32 MCU:STM32Fxx, STM32H5xx, STM32H7xx | | **NXP** | 所有内置以太网的 NXP MCU:IMXRT102x, IMXRT104x, IMXRT105x, IMXRT106x, IMXRT117x, RW612, MCXN94x | | **Microchip** | 内置以太网的 ATSAME54 MCU | | **Renesas** | 内置以太网的 RA5M, RA6M, RA8M MCU | | **Infineon** | 内置以太网的 XMC4, XMC7 MCU | | **Texas Instruments** | 内置以太网的 TM4C, TMS570 MCU | | **Cypress WiFi** | 任何带有 CY43xx WiFi 芯片的 MCU,如 RP2040 Pico-W, RP2350 Pico2-W, Arduino Portenta | | **Wiznet Ethernet** | 任何使用 Wiznet W5500 或 Wiznet 5100 MAC+PHY 芯片的 MCU | | **Cellular** | NRF9160, SIM800 | ## 使用示例 以下简短的代码片段应该能让您了解 API 是多么简单,以及使用它创建应用程序是多么容易。 创建一个提供目录服务的简单 Web 服务器。HTTP 服务器的行为由其事件处理函数指定: ``` #include "mongoose.h" // To build, run: cc main.c mongoose.c // HTTP server event handler function void ev_handler(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; struct mg_http_serve_opts opts = { .root_dir = "./web_root/" }; mg_http_serve_dir(c, hm, &opts); } } int main(void) { struct mg_mgr mgr; // Declare event manager mg_mgr_init(&mgr); // Initialise event manager mg_http_listen(&mgr, "http://0.0.0.0:8000", ev_handler, NULL); // Setup listener for (;;) { // Run an infinite event loop mg_mgr_poll(&mgr, 1000); } return 0; } ``` 实现返回当前时间的 REST API 的 HTTP 服务器。JSON 格式: ``` static void ev_handler(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_HTTP_MSG) { struct mg_http_message *hm = (struct mg_http_message *) ev_data; if (mg_match(hm->uri, mg_str("/api/time/get"), NULL)) { mg_http_reply(c, 200, "", "{%m:%lu}\n", MG_ESC("time"), time(NULL)); } else { mg_http_reply(c, 500, "", "{%m:%m}\n", MG_ESC("error"), MG_ESC("Unsupported URI")); } } } ``` 订阅 `device1/rx` 主题并将收到的消息回显到 `device1/tx` 的 MQTT 客户端: ``` #include "mongoose.h" static const char *s_mqtt_url = "mqtt://broker.hivemq.com:1883"; static struct mg_connection *s_mqtt_conn = NULL; // MQTT connection event handler function static void ev_handler(struct mg_connection *c, int ev, void *ev_data) { if (ev == MG_EV_OPEN) { MG_INFO(("%lu created, connecting to %s ...", c->id, s_mqtt_url)); } else if (ev == MG_EV_MQTT_OPEN) { struct mg_mqtt_opts opts = {.qos = 1, .topic = mg_str("device1/rx")}; mg_mqtt_sub(c, &opts); MG_INFO(("%lu connected, subscribing to %s", c->id, opts.topic.buf)); } else if (ev == MG_EV_MQTT_MSG) { char response[100]; struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data; struct mg_mqtt_opts opts = {.qos = 1, .topic = mg_str("device1/tx")}; mg_snprintf(response, sizeof(response), "Received [%.*s] / [%.*s]", mm->topic.len, mm->topic.buf, mm->data.len, mm->data.buf); opts.message = mg_str(response); mg_mqtt_pub(c, &opts); } else if (ev == MG_EV_CLOSE) { MG_INFO(("%u closing", c->id)); s_mqtt_conn = NULL; } } // Reconnection timer function. If we get disconnected, reconnect again static void timer_fn(void *arg) { struct mg_mgr *mgr = (struct mg_mgr *) arg; if (s_mqtt_conn == NULL) { struct mg_mqtt_opts opts = {.clean = true}; s_mqtt_conn = mg_mqtt_connect(mgr, s_mqtt_url, &opts, ev_handler, NULL); } } int main() { struct mg_mgr mgr; // Mongoose event manager. Holds all connections mg_mgr_init(&mgr); // Initialise event manager mg_timer_add(&mgr, 3000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, &mgr); for (;;) { mg_mgr_poll(&mgr, 1000); // Infinite event loop } return 0; } ``` ## 商业用途 - Mongoose 被数百家企业使用,从 Fortune 500 强巨头如 Siemens、Schneider Electric、Broadcom、Bosch、Google、Samsung、Qualcomm、Caterpillar 到小型企业 - 用于解决广泛的业务需求,例如在设备上实现 Web UI 界面、RESTful API 服务、遥测数据交换、产品远程控制、远程软件更新、远程监控等 - 已部署在全球数以亿计的生产环境设备中 - 请参阅来自我们尊贵客户的 [案例研究](https://mongoose.ws/case-studies/),如 [Schneider Electric](https://mongoose.ws/case-studies/schneider-electric/)(工业自动化)、[Broadcom](https://mongoose.ws/case-studies/broadcom/)(半导体)、[Pilz](https://mongoose.ws/case-studies/pilz/)(工业自动化)等 - 请参阅将 Mongoose 集成到其商业产品中的工程师的 [推荐语](https://mongoose.ws/testimonials/) - 我们提供 [评估和商业许可](https://mongoose.ws/licensing/)、[支持](https://mongoose.ws/support/)、咨询和 [集成服务](https://mongoose.ws/integration/) - 请随时[联系我们](https://mongoose.ws/contact/) ## 安全性 我们要认真对待安全性: 1. Mongoose 仓库运行着由 [GitHub 驱动的持续集成测试](https://github.com/cesanta/mongoose/actions),该测试在每次提交到仓库时都会运行数百个单元测试。我们的 [单元测试](https://github.com/cesanta/mongoose/tree/master/test) 是使用现代地址消毒器技术构建的,有助于尽早发现安全漏洞 2. Mongoose 仓库已集成到 Google 的 [oss-fuzz 持续模糊测试器](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose) 中,该测试器会持续扫描潜在漏洞 3. 我们会收到来自独立安全组的定期漏洞报告,例如 [Cisco Talos](https://www.cisco.com/c/en/us/products/security/talos.html)、[Microsoft Security Response Center](https://www.microsoft.com/en-us/msrc)、[MITRE Corporation](https://www.mitre.org/)、[Compass Security](https://www.compass-security.com/en/) 等。如果发现漏洞,我们会按照行业最佳实践采取行动:暂缓发布,修复软件并通知所有拥有相应订阅的客户 4. 我们的某些客户(例如 NASA)有特定的安全要求并运行独立的安全审计,我们会收到通知,如果出现任何问题,我们会采取与 (3) 类似的行动。 ## 如何报告安全漏洞 请发送电子邮件至 support@cesanta.com,并附上完整信息。 请勿创建 GitHub issue。 ## 文章 嵌入式 Web 服务器、WebUI 集成和嵌入式网络技术的技术指南和深度解析: - [嵌入式 Web 服务器:现代互联设备综合指南](https://mongoose.ws/articles/embedded-web-server-a-comprehensive-guide-for-modern-connected-devices/) - [构建嵌入式 Web 设备仪表盘](https://mongoose.ws/articles/building-embedded-web-device-dashboard/) - [ESP32 设备仪表盘:开发者分步指南](https://mongoose.ws/articles/esp32-device-dashboard/) - [如何构建 STM32 Web 仪表盘](https://mongoose.ws/articles/stm32-device-dashboard/) - [STM32 WebSocket 指南](https://mongoose.ws/articles/stm32-websocket-guide/) - [STM32、ESP32 和嵌入式 Linux 上的 Web 文件管理器](https://mongoose.ws/articles/building-a-web-file-manager-on-stm32-esp32-embedded-linux/) - [Zephyr RTOS 上的 Web 仪表盘](https://mongoose.ws/articles/web-dashboard-on-zephyr-rtos/) - [在 STM32 上限制 TCP/IP RAM 使用](https://mongoose.ws/articles/limiting-tcpip-ram-usage-on-stm32/) - [STM32 以太网详解](https://mongoose.ws/articles/stm32-ethernet-explained/) - [微控制器上的 MQTT](https://mongoose.ws/articles/mqtt-on-a-microcontroller/) - [STM32 OTA 固件更新](https://mongoose.ws/articles/stm32-ota-firmware-update/) - [RP2350 OTA 固件更新](https://mongoose.ws/articles/rp2350-ota-firmware-update/) - [STM32 以太网与缓存](https://mongoose.ws/articles/stm32-ethernet-and-cache/) - [NXP RW612 OTA 固件更新](https://mongoose.ws/articles/rw612-ota-firmware-update/) - [lwIP vs Mongoose - TCP/IP 协议栈集成基准测试](https://mongoose.ws/articles/lwip-vs-mongoose-tcpip-stack-integration/) ## 贡献 欢迎贡献!请遵循以下准则: - 签署 [Cesanta CLA](https://cesanta.com/cla.html) 并发送 GitHub pull request - 确保 PR 只有一个提交,并且只处理一个问题
标签:C/C++, ESP32, HTTP服务器, IoT设备联网, IP 地址批量处理, LangChain, NXP, RTOS, SNTP, ST, TCP, TCP/IP, TCP/IP协议栈, UDP, WebSocket, 事件驱动, 事务性I/O, 依赖分析, 单片机, 嵌入式Web服务器, 嵌入式开发, 嵌入式系统, 工业控制, 并发处理, 开源, 异步DNS, 智能家居, 物联网, 网络安全平台, 网络安全监控, 网络库, 网络编程, 航天软件, 裸机编程, 轻量级, 边缘计算, 非阻塞IO, 驱动开发