mongoose学习(一)Http通信

mongoose简介

mongoose是C/ c++的一个网络库(https://github.com/cesanta/mongoose)。它实现了事件驱动的非阻塞api的TCP, UDP, HTTP, WebSocket, MQTT。自2004年上市以来,被大量的开源和商业产品使用——它甚至在国际空间站上运行!Mongoose使嵌入式网络编程快速、健壮和简单。
Mongoose库使用起来非常简单,只有2个文件,一个.h 一个.cpp,添加到项目中,就可以使用了(参考https://blog.csdn.net/u012234115/article/details/79596826

原理

使用mongoose的搭建服务端或客户端的关键方法如下:
1.mg_mgr_init
①初始化网络库;②初始化链接管理器;③关联用户数据。
2.mg_bind
①从address中拿到端口信息;②调用mg_create_connection,创建connection。设置connection的状态;③开始监听;④connection加入到mgr链接管理器。
3.mg_connect_http
创建outbound HTTP连接。
4.mg_mgr_poll
mg_mgr_poll()迭代所有套接字,接受新连接,发送和接收数据,关闭连接并调用相应事件的事件处理函数。
5.mg_mgr_free
释放操作

mongoose原理介绍请参考此文:https://www.cnblogs.com/gardenofhu/p/6961343.html
这里小编就不在赘述,下面直接上代码~

code

服务端

#include "mongoose.h"

#include <string>

#ifdef WIN32 
#pragma comment(lib, "ws2_32.lib")
#endif

static const char *s_http_port = "8000";

static void ev_handler(struct mg_connection *conn, int ev, void *ev_data) 
{
	// 区分http和websocket
	if (ev == MG_EV_HTTP_REQUEST)
	{
		http_message *hm = (http_message *)ev_data;
		
		//(int)hm->message.len, hm->message.p 中存放客户端发过来的信息,包括post,Host(http地址),Content-Length(信息的长度),以及信息本身。
		//通过 std::string url = std::string(hm->uri.p, hm->uri.len); 可以得到url
		//通过 std::string body = std::string(hm->body.p, hm->body.len);可以得到body中 存储的从客户端发送过来的信息
		std::string req_str = std::string(hm->message.p, hm->message.len);
		printf("got request:\n%s\n", req_str.c_str());

		//TODO.  请求处理
		// eg.  We have received an HTTP request. Parsed request is contained in `hm`.
		//      Send HTTP reply to the client which shows full original request.
		mg_send_head(conn, 200, hm->message.len, "Content-Type: text/plain");
		mg_printf(conn, "%.*s", (int)hm->message.len, hm->message.p);

	}
	else if (ev == MG_EV_WEBSOCKET_HANDSHAKE_DONE ||
		ev == MG_EV_WEBSOCKET_FRAME ||
		ev == MG_EV_CLOSE)
	{
		websocket_message *ws_message = (struct websocket_message *)ev_data;
		//TODO.  请求处理
		//......
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	// mg_mgr是拥有所有活动连接的事件管理器
	struct mg_mgr mgr;
	//mg_connection描述连接
	struct mg_connection *nc;
    
    //初始化事件管理器
	mg_mgr_init(&mgr, NULL);

	//创建连接
	printf("Starting web server on port %s\n", s_http_port);
	nc = mg_bind(&mgr, s_http_port, ev_handler);
	if (nc == NULL) {
		printf("Failed to create listener\n");
		return 1;
	}
	// Set up HTTP server parameters,  for both http and websocket
	mg_set_protocol_http_websocket(nc);

	//通过调用循环创建一个事件mg_mgr_poll()循环:
	for (;;) {
		mg_mgr_poll(&mgr, 1000);
	}
	mg_mgr_free(&mgr);

	return 0;
}

客户端

#include "stdafx.h"
#include "mongoose.h"

#include <string>
#include <iostream>


static const char *url = "127.0.0.1:8000";//"http://www.baidu.com";
static int exit_flag = 0;


static void ev_handler(mg_connection *conn, int ev, void *ev_data)
{
	http_message *hm = (struct http_message *) ev_data;
	int connect_status;
	switch (ev) {
	case MG_EV_CONNECT:
		connect_status = *(int *)ev_data;
		if (connect_status != 0)
		{
			printf("Error connecting to server, error code: %d\n", connect_status);
			exit_flag = 1;
		}
		break;
	case MG_EV_HTTP_REPLY: //建立http服务器并收到数据
		{
			printf("Got http reply:\n%.*s\n", (int)hm->body.len, hm->body.p);
			std::string rsp = std::string(hm->body.p, hm->body.len);
			conn->flags |= MG_F_SEND_AND_CLOSE;
			exit_flag = 1; // 每次收到请求后关闭本次连接,重置标记

			//TODO. 处理响应数据
			std::cout << "http rsp1: " << rsp << std::endl;
		}
		break;
	case MG_EV_CLOSE:
		if (exit_flag == 0)
		{
			printf("Server closed connection\n");
			exit_flag = 1;
		};
		break;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	struct mg_mgr mgr;    // Event manager
	mg_mgr_init(&mgr, NULL);    // Initialise event manager

	bool done = false;  // Event handler flips it to true
	mg_connect_http(&mgr, ev_handler, url, NULL, NULL);

	while (exit_flag == 0) {
		mg_mgr_poll(&mgr, 1000);
	}
	mg_mgr_free(&mgr);

	getchar();

	return 0;
}

运行结果

在这里插入图片描述
OK, 以上就是运用mongoose进行Http通信的简单例子。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Mongoose 是一个嵌入式 Web 服务器,它可以响应 HTTP 客户端的请求。在 Mongoose ,你可以通过编写代码来处理 HTTP 请求,并返回响应数据。 以下是一个简单的示例代码,展示了如何使用 Mongoose 响应 HTTP 请求: ``` #include "mongoose.h" static const char *html = "<html><body><h1>Hello, world!</h1></body></html>"; static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { struct http_message *hm = (struct http_message *) ev_data; switch (ev) { case MG_EV_HTTP_REQUEST: mg_printf(nc, "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Content-Length: %d\r\n" "\r\n" "%s", (int) strlen(html), html); nc->flags |= MG_F_SEND_AND_CLOSE; break; default: break; } } int main(void) { struct mg_mgr mgr; struct mg_connection *nc; mg_mgr_init(&mgr, NULL); nc = mg_bind(&mgr, "8080", ev_handler); mg_set_protocol_http_websocket(nc); for (;;) { mg_mgr_poll(&mgr, 1000); } mg_mgr_free(&mgr); return 0; } ``` 在这个示例,我们创建了一个名为 `ev_handler` 的回调函数,它会在 Mongoose 接收到 HTTP 请求时被调用。在这个函数,我们使用 `mg_printf` 函数来向客户端发送 HTTP 响应。这个响应包含了一个简单的 HTML 页面,其包含了一条问候语。 在 `main` 函数,我们使用 `mg_bind` 函数来创建一个监听在端口 `8080` 上的 HTTP 服务器。然后,我们使用 `mg_set_protocol_http_websocket` 函数来为这个服务器设置 HTTP 协议和 WebSocket 协议。 最后,我们使用 `mg_mgr_poll` 函数来等待事件的发生。在这个示例,我们只关注 HTTP 请求事件。当这个事件发生时,我们就会调用 `ev_handler` 函数来处理它。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值