一、Mongoose 的介绍
Mongoose 是一款嵌入式 Web 服务器库,具有跨平台、轻量级、支持多种网络协议、稳定可靠等特点。
国内下载地址:
https://gitee.com/mirrors/mongoose.git
官方链接:
https://mongoose.ws/
参考说明文档:
https://mongoose.ws/documentation/
二、移植
Linux下移植非常简单,只需要将mongoose.c和mongoo.h文件复制到工程中即可。
三、测试
根据手册进行简单测试,手册如下:
测试代码如下:
// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved
#include
#include "mongoose.h"
static int s_debug_level = MG_LL_INFO;
static const char *s_root_dir = ".";
static const char *s_listening_address = "http://0.0.0.0:8000";
static const char *s_enable_hexdump = "no";
static const char *s_ssi_pattern = "#.html";
// Handle interrupts, like Ctrl-C
static int s_signo;
static void signal_handler(int signo) {
s_signo = signo;
}
// Event handler for the listening connection.
// Simply serve static files from `s_root_dir`
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{
if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_http_match_uri(hm, "/api/hello")) { // On /api/hello requests,
mg_http_reply(c, 200, "", "{%m:%d}\n",
MG_ESC("status"), 1); // Send dynamic JSON response
} else { // For all other URIs,
struct mg_http_serve_opts opts = {.root_dir = "."}; // Serve files
mg_http_serve_dir(c, hm, &opts); // From root_dir
}
}
}
static void usage(const char *prog) {
fprintf(stderr,
"Mongoose v.%s\n"
"Usage: %s OPTIONS\n"
" -H yes|no - enable traffic hexdump, default: '%s'\n"
" -S PAT - SSI filename pattern, default: '%s'\n"
" -d DIR - directory to serve, default: '%s'\n"
" -l ADDR - listening address, default: '%s'\n"
" -v LEVEL - debug level, from 0 to 4, default: %d\n",
MG_VERSION, prog, s_enable_hexdump, s_ssi_pattern, s_root_dir,
s_listening_address, s_debug_level);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
char path[MG_PATH_MAX] = ".";
struct mg_mgr mgr;
struct mg_connection *c;
int i;
// Parse command-line flags
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-d") == 0) {
s_root_dir = argv[++i];
} else if (strcmp(argv[i], "-H") == 0) {
s_enable_hexdump = argv[++i];
} else if (strcmp(argv[i], "-S") == 0) {
s_ssi_pattern = argv[++i];
} else if (strcmp(argv[i], "-l") == 0) {
s_listening_address = argv[++i];
} else if (strcmp(argv[i], "-v") == 0) {
s_debug_level = atoi(argv[++i]);
} else {
usage(argv[0]);
}
}
// Root directory must not contain double dots. Make it absolute
// Do the conversion only if the root dir spec does not contain overrides
if (strchr(s_root_dir, ',') == NULL) {
realpath(s_root_dir, path);
s_root_dir = path;
}
// Initialise stuff
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
mg_log_set(MG_LL_DEBUG);//mg_log_set(s_debug_level);
mg_mgr_init(&mgr);
if ((c = mg_http_listen(&mgr, s_listening_address, cb, &mgr)) == NULL) {
MG_ERROR(("Cannot listen on %s. Use http://ADDR:PORT or :PORT",
s_listening_address));
exit(EXIT_FAILURE);
}
if (mg_casecmp(s_enable_hexdump, "yes") == 0) c->is_hexdumping = 1;
// Start infinite event loop
MG_INFO(("Mongoose version : v%s", MG_VERSION));
MG_INFO(("Listening on : %s", s_listening_address));
MG_INFO(("Web root : [%s]", s_root_dir));
while (s_signo == 0) mg_mgr_poll(&mgr, 1000);
mg_mgr_free(&mgr);
MG_INFO(("Exiting on signal %d", s_signo));
return 0;
}
在vs code中打开终端,输入如下指令
可以看到程序自动运行。
打开浏览器输入ip地址和端口,可看到如下:
输入测试指令,可获取到返回信息
http://192.168.1.195:8000/api/hello
简单介绍下相关的函数和结构体,如下:
简单示例,post和get方法:
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{
struct mg_http_message *hm = ev_data;
if (ev == MG_EV_HTTP_MSG)
{
if (strstr(hm->method.ptr, "POST"))
{
if (mg_http_match_uri(hm, "/haha"))
{
printf("这是POST请求\n");
printf("body:%s\n",hm->body);
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{%.*s:%.*s}", (strlen("已经收到client请求")),"已经收到client请求", hm->message.len,hm->message);
}
else
{
mg_http_reply(c, 500, NULL, "{%.*s:%.*s}", (strlen("已经收到client请求")),"已经收到client请求",hm->message.len, hm->message);
}
}
else if (strstr(hm->method.ptr, "GET"))
{
if (mg_http_match_uri(hm, "/haha"))
{
printf("这是GET请求\n");
mg_http_reply(c, 200, "Content-Type: application/json\r\n", "{%.*s:%.*s}", (strlen("已经收到client请求")),"已经收到client请求", hm->message.len,hm->message);
}
else
{
mg_http_reply(c, 500, NULL, "{%.*s:%.*s}", (strlen("已经收到client请求")),"已经收到client请求", hm->message.len,hm->message);
}
}
else
{
mg_http_reply(c, 500, NULL, "{%.*s:%.s}", (strlen("已经收到client请求")),"已经收到client请求",hm->message.len,hm->message);
}
}
(void) fn_data;
}
欢迎关注公众号:嵌入式学习与实践