Mongoose 是什么?
Mongoose 是一个非常小巧易用的网络库。它为 TCP、UDP、HTTP、WebSocket、MQTT 实现了基于事件驱动的非阻塞 API,它的只有两个文件,非常适合在嵌入式系统上使用。
Mongoose官网:Mongoose - an embedded Web Server, MQTT and Websocket library
这个库全是C函数,我封装了两个类,实现TCP的通信,更方便使用。
Mongoose封装类实现
封装类支持Tcp Client模式和Tcp Server模式。
#ifndef _CONN_INTERFACE_H_
#define _CONN_INTERFACE_H_
#include <string.h>
#include <stdlib.h>
#include <memory>
#include "mongoose.h"
#include <unordered_map>
using namespace std;
class ConnInterface {
public:
struct mg_connection* c_conn;
struct mg_mgr* c_mgr;
std::string c_url;
private:
static void event_callback(struct mg_connection *c, int ev, void *ev_data, void *fn_data);
public:
ConnInterface();
~ConnInterface();
string get_net_url();
std::string get_url(const char* ip, uint16_t port);
int init(struct mg_mgr* mgr);
int connect(const char* url);
int connect(const char* ip, uint16_t port);
int send(const char *buf, int len);
int send(struct mg_connection* conn, const char *buf, int len);
int listen(const char* url);
int listen(const char* ip, uint16_t port);
void close();
void handle_msg(struct mg_connection* conn, const char* msg, int len);
};
#endif
CPP文件如下。接收数据后如何解析数据和利用,请根据你的业务需要,在handle_msg中实现或者调用你自己的程序。
#include"ConnInterface.h"
#include <thread>
ConnInterface::ConnInterface() {
}
ConnInterface::~ConnInterface() {
close();
}
void ConnInterface::event_callback(struct mg_connection* c, int ev, void* ev_data, void* fn_data) {
ConnInterface* tcp_if = (ConnInterface*) fn_data;
if (ev == MG_EV_OPEN) {
printf("[%s]初始化完成", tcp_if->c_url.c_str());
} else if (ev == MG_EV_ACCEPT) {
print("[%]接收到一个了链接,状态[%d]", tcp_if->c_url.c_str(), c->is_connecting);
} else if (ev == MG_EV_CONNECT) {
printf("[%s]网络状态[%d]", tcp_if->c_url.c_str(), c->is_connecting);
} else if (ev == MG_EV_READ) {
char* mess = (char*) c->recv.buf;
printf("[%s]收到数据%d", tcp_if->c_url.c_str(), c->recv.len);
tcp_if->handle_msg(c, (const char *)c->recv.buf, c->recv.len);
mg_iobuf_del(&c->recv, 0, c->recv.len);
} else if (ev == MG_EV_CLOSE) {
printf("网[%s]关闭 网络状态[%d]", tcp_if->c_url.c_str(), c->is_closing);
sleep(2);
tcp_if->connect(tcp_if->c_url.c_str());
} else if (ev == MG_EV_ERROR) {
printf("[%s]连接失败: %s", tcp_if->c_url.c_str(), (char *) ev_data);
} else if (ev == MG_EV_POLL) {
if(c->is_connecting != 0){
print("CLIENT send data");
}
} else {
printf("网络[%s]连接,event_code = %d", tcp_if->c_url.c_str(), ev);
}
}
string ConnInterface::get_net_url() {
return c_url;
}
int ConnInterface::init(struct mg_mgr* mgr){
if(NULL == mgr){
return -1;
}
c_mgr = mgr;
return 0;
}
std::string ConnInterface::get_url(const char* ip, uint16_t port){
char url[256] = {0};
if(NULL == ip){
c_url = "";
return c_url;
}
snprintf(url, sizeof(url), "tcp://%s:%d", ip, port);
c_url = url;
return c_url;
}
int ConnInterface::connect(const char* url){
printf("正在连接%s ", url);
c_conn = mg_connect(c_mgr, url, ConnInterface::event_callback, this);
int ret = 0;
if (c_conn == NULL) {
printf("网络【%s】创建连接失败", url);
ret = -1;
} else {
printf("网络【%s】创建连接成功", url);
ret = 0;
}
return ret;
}
int ConnInterface::connect(const char* ip, uint16_t port){
if(get_url(ip, port).empty()){
printf("非法网络参数:%s ", c_url.c_str());
return -1;
}
return connect(c_url.c_str());
}
int ConnInterface::send(const char *buf, int len){
if((NULL == buf) || (1 > len)){
return -1;
}
if(true == mg_send(c_conn, buf, len)){
printf("[%s]TCP数据发送成功", c_url.c_str());
return 0;
}else{
printf("[%s]TCP数据发送失败", c_url.c_str());
}
return -1;
}
int ConnInterface::send(struct mg_connection* conn, const char *buf, int len){
if((NULL == buf) || (1 > len) || (NULL == conn)){
return -1;
}
if(true == mg_send(conn, buf, len)){
printf("网络【%s】TCP数据发送成功", c_url.c_str());
return 0;
}else{
printf("网络【%s】TCP数据发送失败", c_url.c_str());
}
return -1;
}
void ConnInterface::close(){
}
int ConnInterface::listen(const char* url){
printf("网络初始化,正在监听%s ", url);
c_conn = mg_listen(c_mgr, url, ConnInterface::event_callback, this);
int ret = 0;
if (c_conn == NULL) {
printf("网络【%s】创建监听失败", url);
ret = -1;
} else {
Cprintf("网络【%s】创建监听成功", url);
ret = 0;
}
return ret;
}
int ConnInterface::listen(const char* ip, uint16_t port){
if(get_url(ip, port).empty()){
printf("非法网络参数:%s ", c_url.c_str());
return -1;
}
return listen(c_url.c_str());
}
void ConnInterface::handle_msg(struct mg_connection* conn, const char* msg, int len){
//ToDo:
//接收数据数据
}
对外接口即网络管理类,使用此类调用init接口即可。
#ifndef __NET_MANAGER_H__
#define __NET_MANAGER_H__
#include <memory>
#include "ConnInterface.h"
typedef enum {
WORKING_MODE_CLIENT = 0,
WORKING_MODE_SERVER = 1
}WORKING_MODE;
class NetManager
{
private:
/* data */
static NetManager c_tcp_manager;
struct mg_mgr c_mgr;
std::shared_ptr<ConnInterface> c_tcp_if;
public:
NetManager(/* args */);
~NetManager();
static NetManager& getInstance();
int init(const char* ip, uint16_t port, WORKING_MODE mode = WORKING_MODE_SERVER);
int send(const char *buf, int len);
void close();
};
#endif /* __NET_MANAGER_H__ */
CPP实现
#ifndef __NET_MANAGER_H__
#define __NET_MANAGER_H__
#include <memory>
#include "ConnInterface.h"
typedef enum {
WORKING_MODE_CLIENT = 0,
WORKING_MODE_SERVER = 1
}WORKING_MODE;
class NetManager
{
private:
/* data */
static NetManager c_tcp_manager;
struct mg_mgr c_mgr;
std::shared_ptr<ConnInterface> c_tcp_if;
public:
NetManager(/* args */);
~NetManager();
static NetManager& getInstance();
int init(const char* ip, uint16_t port, WORKING_MODE mode = WORKING_MODE_SERVER);
int send(const char *buf, int len);
void close();
};
#endif /* __NET_MANAGER_H__ */
点击 下载 Mongoose封装类及mongoose库文件