Mongoose封装类实现

本文介绍了Mongoose,一个用于TCP、UDP、HTTP、WebSocket和MQTT的轻量级网络库,特别适合嵌入式系统。文章详细阐述了库的特性、C++封装的类实现以及如何使用和处理网络事件。
摘要由CSDN通过智能技术生成

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库文件​​​​​​​

Mongoose是一个优秀的Node.js的MongoDB对象建模工具,用于在应用程序中与MongoDB数据库进行交互。在Mongoose中,可以使用HTTP的GET和POST方法来与数据库进行交互。 要使用Mongoose实现GET方法,首先需要建立与MongoDB的连接。可以使用`mongoose.connect()`方法连接到MongoDB数据库。连接成功后,可以使用`Model.find()`方法来获取数据库中的数据。`Model.find()`方法接受一个查询条件对象作为参数,可以根据指定的条件筛选出满足条件的文档数据并返回结果。 例如,可以定义一个名为"User"的模型,然后通过调用`User.find()`方法来获取所有的用户信息: ```javascript const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/test', { useNewUrlParser: true }); const userSchema = new mongoose.Schema({ name: String, age: Number }); const User = mongoose.model('User', userSchema); User.find({}, (err, users) => { if (err) { console.error(err); } else { console.log(users); } }); ``` 上述例子中,`User.find({}, callback)`表示查询条件为空,即获取所有文档数据。回调函数中的`err`参数表示错误信息,`users`参数表示满足条件的文档数据。 要使用Mongoose实现POST方法,需要先建立连接并定义一个模型。然后,可以使用`Model.create()`方法创建新的文档。 例如,可以继续使用上述的"User"模型来创建新的用户: ```javascript const newUser = { name: 'John', age: 25 }; User.create(newUser, (err, user) => { if (err) { console.error(err); } else { console.log(user); } }); ``` 上述例子中,`User.create()`方法接受一个包含要创建文档的数据对象。回调函数中的`err`参数表示错误信息,`user`参数表示新增的文档数据。 通过以上的方法,就可以使用Mongoose实现GET和POST方法与MongoDB数据库进行交互。还可以结合Express.js等框架来构建完整的Web应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

previewer1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值