【Mongoose学习笔记一】简单使用

目录

  • 参考链接
  • 简介
  • 入门使用
    • 实验目的:
    • 步骤:
    • 官方提供的例程
    • 修改官方例程
    • 函数简介
      • Core
      • HTTP

参考链接

1、github项目地址:https://github.com/cesanta/mongoose
2、使用手册:https://mongoose.ws/documentation
3、https://mongoose.ws

简介

Mongoose是一个C/C++的网络库,它为TCP、UDP、HTTP、WebSocket、MQTT实现了事件驱动的、非阻塞的API。

入门使用

实验目的:

做一个简单的HTTP服务端,可以在浏览器中显示hello world

步骤:

  • 首先下载Mongoose的源码,将源码中的mongoose.cmongoose.h文件拷贝到工程目录中
  • 使用官方文档中的例程修改程序
  • 编写cmake,编译

官方提供的例程

#include "mongoose.h"

static void fn(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_print_esc, 0, "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
    }
  }
}

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

主函数中,首先要实例化一个对象,用来管理事件。
然后初始化事件管理结构体,创建http监听,循环监听连接的客户端。
最后退出程序时清除事件管理结构体

fn是http事件的回调函数,在该函数中首先判断是否是http事件,然后判断URI,如果匹配成功则在网页中显示相应的内容,否则显示根目录中的内容

编写cmake文件

cmake_minimum_required(VERSION 3.16)		
project(mongoose_test)
add_executable(mongoose_test)
target_sources(mongoose_test PRIVATE main.c mongoose/mongoose.c)
target_include_directories(mongoose_test PRIVATE mongoose)

第1行:版本要求
第2行:工程名
第3行:生成的可执行文件名
第4行:需要的源码文件
第5行:包含的目录

编译,运行,在浏览器中输入ip地址和端口号,则在网页中会显示当前目录中的内容,这是因为在本地并没有"/api/hello"这个文件。所以如果想显示helloworld则需要在本地写一个html文件,并将路径写到"/api/hello"这个位置。
【Mongoose学习笔记一】简单使用_第1张图片

修改官方例程

if (mg_http_match_uri(hm, "/api/hello"))
修改为if (mg_http_match_uri(hm, "html/index.html"))

并在工程的根目录下写一个index.html文件(文件名是index.html时,直接输入ip地址和端口号即可,此时的http发送的请求就是请求index.html文件)

<html>
<head>
    <meat charset="utf-8">
    <title> mongoose test title>
head>

<body>
    <b><font color="blue"> hello world font>b>
body>

html>

编译执行,在浏览器中输入http://0.0.0.0:8000/,则显示下图
【Mongoose学习笔记一】简单使用_第2张图片

函数简介

Core

  1. 事件管理结构体

事件管理结构,包含活动连接列表以及一些管理信息。
struct mg_mgr

	struct mg_mgr {
		struct mg_connection *conns;  // List of active 			connections
		struct mg_dns dns4;           // DNS for IPv4
		struct mg_dns dns6;           // DNS for IPv6
		int dnstimeout;               // DNS resolve timeout in milliseconds
		unsigned long nextid;         // Next connection ID
		void *userdata;               // Arbitrary user data pointer
	};
  1. 连接结构体
struct mg_connection {
  struct mg_connection *next;  // Linkage in struct mg_mgr :: connections
  struct mg_mgr *mgr;          // Our container
  struct mg_addr loc;          // Local address
  struct mg_addr rem;          // Remote address
  void *fd;                    // Connected socket, or LWIP data
  unsigned long id;            // Auto-incrementing unique connection ID
  struct mg_iobuf recv;        // Incoming data
  struct mg_iobuf send;        // Outgoing data
  mg_event_handler_t fn;       // User-specified event handler function
  void *fn_data;               // User-specified function parameter
  mg_event_handler_t pfn;      // Protocol-specific handler function
  void *pfn_data;              // Protocol-specific function parameter
  char data[MG_DATA_SIZE];     // Arbitrary connection data, MG_DATA_SIZE defaults to 32 bytes
  void *tls;                   // TLS specific data
  unsigned is_listening : 1;   // Listening connection
  unsigned is_client : 1;      // Outbound (client) connection
  unsigned is_accepted : 1;    // Accepted (server) connection
  unsigned is_resolving : 1;   // Non-blocking DNS resolve is in progress
  unsigned is_connecting : 1;  // Non-blocking connect is in progress
  unsigned is_tls : 1;         // TLS-enabled connection
  unsigned is_tls_hs : 1;      // TLS handshake is in progress
  unsigned is_udp : 1;         // UDP connection
  unsigned is_websocket : 1;   // WebSocket connection
  unsigned is_hexdumping : 1;  // Hexdump in/out traffic
  unsigned is_draining : 1;    // Send remaining data, then close and free
  unsigned is_closing : 1;     // Close and free the connection immediately
  unsigned is_full : 1;        // Stop reads, until cleared
  unsigned is_resp : 1;        // Response is still being generated
  unsigned is_readable : 1;    // Connection is ready to read
  unsigned is_writable : 1;    // Connection is ready to write
}
  1. 初始化事件管理结构体
    mg_mgr_init()
    函数原型:

    void mg_mgr_init(struct mg_mgr *mgr);
    

    主要功能:

     将活动连接列表设置为NULL
     设置IPv4和IPv6的默认DNS服务器
     设置默认DNS查找超时时间
    

    参数:

     mgr:指向需要初始化的mg_mgr结构的指针
    

    返回值:

     无返回值
    
  2. 执行单个轮询
    mg_mgr_poll()
    函数原型:

    void mg_mgr_poll(struct mg_mgr *mgr, int ms);
    

    主要功能:

     1. 查看是否有传入数据。如果有,读入c->recv,发送MG_EV_READ事件
     2. 查看c->send缓冲区是否有数据,有写入它,发送MG_EV_WRITE事件
     3. 如果连接正在侦听,则接受传入的连接(如果有),并向其发送MG_EV_ACCEPT事件
     4. 发送MG_EV_POLL事件
    

    参数:

     mgr:要使用的事件管理器
     ms: 超时时间(ms为单位)
    

    返回值:

     无返回值
    
  3. 关闭连接
    mg_mgr_free()
    函数原型:

    void mg_mgr_free(struct mg_mgr *mgr);
    

    主要功能:

     关闭所有连接,并释放所有资源
    

    参数:

     mgr:要进行清理事件管理器
    

    返回值:

     无返回值
    

HTTP

  1. struct mg_http_message结构体
    struct mg_http_message()
    函数原型:

    struct mg_http_message {
    	struct mg_str method, uri, query, proto;             // Request/response line
    	 struct mg_http_header 	headers[MG_MAX_HTTP_HEADERS];  // Headers
    	 struct mg_str body;                                  // Body
    	 struct mg_str message;                               // Request line + headers + body
    };
    

    主要功能:

     结构表示HTTP消息
    

【Mongoose学习笔记一】简单使用_第3张图片

  1. 创建http listener
    mg_http_listen()
    函数原型:

    struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,
    									mg_event_handler_t fn, void *fn_data);
    

    主要功能:

    创建HTTP侦听器
    

    参数:

    mgr:事件管理结构体
    url:指定要监听的本地IP地址和端口,例如http://0.0.0.0:8000
    fn:事件处理函数
    fn_data:一个任意指针,在调用事件处理程序时作为fn_data传递。该指针也以c->fn_data的形式存储在连接结构中
    

    返回值:

    指向已创建连接的指针,如果出现错误,则为NULL
    
  2. struct mg_http_serve_opts
    struct mg_http_serve_opts
    函数原型:

    struct mg_http_serve_opts {
    	const char *root_dir;       // Web root directory, must be non-NULL
    	const char *ssi_pattern;    // SSI file name pattern, e.g. #.shtml
    	const char *extra_headers;  // Extra HTTP headers to add in responses
    	const char *mime_types;     // Extra mime types, ext1=type1,ext2=type2,..
    	const char *page404;        // Path to the 404 page, or NULL by default
    	struct mg_fs *fs;           // Filesystem implementation. Use NULL for POSIX
    };
    

    主要功能:

     传递给mg_http_serve_dir()和mg_http_serve_file()的结构,它驱动这两个函数的行为
    
  3. mg_http_serve_dir()
    mg_http_serve_dir()
    函数原型:

    struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url,
    									mg_event_handler_t fn, void *fn_data);
    

    主要功能:

     根据给定的选项提供静态文件
    

    参数:

     c:连接使用
     hm:HTTP消息,应该被服务
     options:服务选项。注意选项。Root_dir可以选择接受额外的逗号分隔的uri=path对,
    

    返回值:

     无返回值
    

    注意

     为了启用SSI,您需要设置-DMG_ENABLE_SSI=1构建标志
     避免使用 "../",在root_dir目录下。如果需要引用上级目录,请使用绝对路径
    
  4. 匹配URI
    mg_http_match_uri()
    函数原型:

    bool mg_http_match_uri(const struct mg_http_message *hm, const char *glob);
    

    主要功能:

     检查HTTP请求是否匹配给定的glob模式
    

    参数:

     hm:要匹配的HTTP消息
     glob:模式,要匹配地址
    

    返回值:

     如果HTTP请求匹配给定的glob模式,则为True;假的,否则
    
  5. mg_http_reply()
    mg_http_reply()
    函数原型:

    	void mg_http_reply(struct mg_connection *c, int status_code,
                   const char *headers, const char *body_fmt, ...);
    

    主要功能:

     使用printf()语义发送简单的HTTP响应。
     该函数根据body_fmt格式设置响应体,并自动添加正确的Content-Length报头。额外的头可以通过headers参数传递。
    

    参数:

     c:连接使用
     status_code:HTTP响应码
     headers:额外的头,默认为NULL。如果不是NULL,必须以\r\n结尾
     fmt:HTTP正文的格式字符串,采用printf语义
    

    返回值:

     无返回值
    

【Mongoose学习笔记一】简单使用_第4张图片

你可能感兴趣的:(mongoose使用,学习,笔记)