官方链接:https://github.com/cesanta/mongoose
[C++]-网络库mongoose简介_alwaysrun的博客-CSDN博客_c++ mongoose
Mongoose-基于C的Web服务器介绍和使用 - 百度文库
https://blog.csdn.net/qianlixiaomage/article/details/105568130
Mongoose库设计理念缓冲区事件处理函数事件连接flagsHttp示例RESTful Server
Mongoose是C语言网络库,为TCP、UDP、HTTP、WebSocket、CoAP、MQTT实现了事件驱动型的非阻塞api。
Mongoose库
Mongoose是出名的嵌入式网络编程库(https://github.com/cesanta/mongoose);只需微小的静态和运行时占用空间,功能包括:
- 跨平台:适用于Linux / UNIX,MacOS,QNX,eCos,Windows,Android,iPhone,FreeRTOS
- 对PicoTCP嵌入式TCP / IP堆栈,LWIP嵌入式TCP / IP堆栈的本机支持
- 适用于各种嵌入式板卡:TI CC3200,TI MSP430,STM32,ESP8266;在所有基于Linux的板上,例如Raspberry PI,BeagleBone等
- 具有简单的基于事件的API的单线程,异步,非阻塞内核
- 内置协议:
- 普通TCP,普通UDP,SSL / TLS(单向或双向),客户端和服务器
- HTTP客户端和服务器
- WebSocket客户端和服务器
- MQTT客户端和服务器
- CoAP客户端和服务器
- DNS客户端和服务器
- 异步DNS解析器
- 微小的静态和运行时占用空间
- 源代码均符合ISO C和ISO C ++
- 易于集成:只需将mongoose.c和mongoose.h文件复制到构建树中
设计理念
Mongoose的三个基本数据结构:
每个链接都使用mg_connection进行描述,一个连接可以是:
-
outbound(出站)链接:通过调用mg_connect()产生;
-
listening(监听)链接:通过调用mg_bind()产生;
-
inbound(入站)链接:listening链接所收到的链接;
Mongoose应用应遵循事件驱动模式,通过mg_mgr_poll()遍历所有的套接字,接受新链接、发送、接收数据、关闭链接;并为各自的事件调用事件处理函数。
缓冲区
每个连接都有一个发送和接收缓冲区:
-
mg_connection::send_mbuf
:将接收到的数据加到recv_mbuf
后面,并触发一个MG_EV_RECV
事件; -
mg_connection::recv_mbuf
:用户发送数据(mg_send()
或mg_printf()
)时,输出函数将数据追加到send_mbuf
;成功地将数据写到socket后,丢弃缓冲区中的数据并触发一个MG_EV_SEND
事件;
连接关闭后,触发一个MG_EV_CLOSE
事件。
事件处理函数
每个链接都有其与之相关的事件处理函数,是数据处理的关键元素。
参数说明:
-
mg_connection *nc
:触发事件的连接;内部有void *user_data
字段,可保存用户自定义信息; -
int ev
:事件编号; -
void *ev_data
: 事件数据指针(不同的事件有不同的意义)
事件
Mongoose接受传入连接、读取和写入数据,并在适当时机触发对应指定事件:
-
出站连接:
MG_EV_CONNECT
-> (MG_EV_RECV
,MG_EV_SEND
,MG_EV_POLL
…) ->MG_EV_CLOSE
-
入站连接:
MG_EV_ACCEPT
-> (MG_EV_RECV
,MG_EV_SEND
,MG_EV_POLL
…) ->MG_EV_CLOSE
核心事件说明:
-
MG_EV_ACCEPT
: 接收到新连接,void *ev_data
是远程端的union socket_address
。 -
MG_EV_CONNECT
: 当mg_connect()
创建了一个新出站链接时(无论连接是否成功),void *ev_data
是int *success
;当success
是0,则连接已经建立,否则包含一个错误码(mg_connect_opt()
函数来查看错误码)。 -
MG_EV_RECV
:接收数据并追加到recv_mbuf
时触发。void *ev_data
是int *num_received_bytes
(接收到的数据长度)。通常,事件处理函数应通过nc->recv_mbuf
检查接收数据,并通过mbuf_remove()
丢弃已处理的数据(用户有责任从接收缓冲区丢弃已处理的数据)。 -
MG_EV_SEND
: 已将数据写入到socket中,并且已经丢弃写入到mg_connection::send_mbuf
的数据;void *ev_data
是int *num_sent_bytes
。 -
MG_EV_POLL
:在每次调用mg_mgr_poll()
时触发。该事件被用于做任何事情,例如,检查某个超时是否已过期并关闭连接或发送心跳消息等。 -
MG_EV_TIMER
: 当mg_set_timer()
调用后触发。
连接flags
每个链接都有flags位域。
由事件处理程序设置的链接flags列表:
-
MG_F_FINISHED_SENDING_DATA:告诉mongoose所有数据已经追加到send_mbuf,只要mongoose将数据写入socket,此链接就会关闭。
-
MG_F_BUFFER_BUT_DONT_SEND:告诉mongoose追加数据到send_mbuf,但数据不要马上发送,因为此数据稍后会被修改。然后通过清除MG_F_BUFFER_BUT_DONT_SEND标志将数据发送出去。
-
MG_F_CLOSE_IMMEDIATELY:告诉mongoose立即关闭链接,通常在产生错误后发送此事件。
-
MG_USER_1,MG_USER_2,MG_USER_3,MG_USER_4:开发者可用它来存储特定应用程序的状态
由mongoose设置的flags:
-
MG_F_SSL_HANDSHAKE_DONE:ssl握手完成时设置;
-
MG_F_CONNECTING:在mg_connect()调用后链接处于链接状态,但未完成链接时设置;
-
MG_F_LISTENING:在监听中;
-
MG_F_UDP:链接是udp时设置;
-
MG_F_WEBSOCKET:链接是websocket时设置;
-
MG_F_WEBSOCKET_NO_DEFRAG:如果用户想关闭websocket的自动帧碎片整理功能,则由用户设置此标记。
Http示例
HTTP请求中主要消息格式为:
RESTful Server
对于Http请求,MG_EV_HTTP_MSG为接收到消息时触发的事件。
mg_http_message中存放的是Http请求的消息,通过mg_http_reply来应答Http请求。
HTTP实例:HTTP server
1,使用mg_bind()或者mg_bind_opt()创建立监听链接
2.调用mg_set_protocol_http_websocket()去监听所有链接。此函数附加了一个内置的http事件处理事件,用于解析并触发特定的HTTP事件。例如当HTTP请求被完全缓冲时,内置的HTTP处理程序将解析请求并使用MG_EV_HTTP_REQUEST事件调用用户定义的事件处理函数,并将HTTP请求解析为事件数据。
3.创建事件处理函数。事件处理程序接收所有的事件(低级别TCP事件(MG_EV_RECV)和高级别HTTP事件(MG_EV_HTTP_REQUEST))。通常事件处理函数应该只处理高级别事件MG_EV_HTTP_REQUEST
下面是HTTP server的实例代码,其中省略了错误检查
使能SSL(HTTPS)
在http服务器端使能ssl需要按照如下步骤:
1.获取ssl证书和私钥文件
2.声明struct mg_bind_opts,初始化化ssl_cert和ssl_key
3.使用mg_bind_opt()去创建监听socket
实例:(更多介绍:查看examples中的https server 实例)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2018-03-14 多线程使用信号量sem_init,sem_wait,sem_post
2017-03-14 Websocket协议的学习、调研和实现
2017-03-14 HTTP协议建立连接、通讯与关闭连接全过程
2017-03-14 HTTP协议学习笔记---HTTP持久连接和如何正确地关闭HTTP连接
2017-03-14 linux route命令的使用详解
2016-03-14 WiFi基本知识 .
2013-03-14 Windows界面编程第七篇 文件拖拽(文件拖放)