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通信的简单例子。

猜你喜欢

转载自blog.csdn.net/lt4959/article/details/112870204
今日推荐