C++利用mongoose搭建http服务端和客户端

官网
官网有详细的说明和丰富的例子,有兴趣的可以去看看

服务端

http_server_sample

#include "mongoose.h"

static const char *s_http_port = "8000";

static void ev_handler(struct mg_connection *c, int ev, void *p) {
  if (ev == MG_EV_HTTP_REQUEST) {
    struct http_message *hm = (struct http_message *) p;

    // We have received an HTTP request. Parsed request is contained in `hm`.
    // Send HTTP reply to the client which shows full original request.
    //我们收到一个HTTP请求。解析后的请求包含在“hm”中。
    //向显示完整原始请求的客户端发送HTTP回复。
    
    //(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中 存储的从客户端发送过来的信息
    mg_send_head(c, 200, hm->message.len, "Content-Type: text/plain");
    mg_printf(c, "%.*s", (int)hm->message.len, hm->message.p);
  }
}

int main(void) {
//mg_mgr是拥有所有活动连接的事件管理器
  struct mg_mgr mgr;
//mg_connection描述连接
  struct mg_connection *c;
  
//初始化
  mg_mgr_init(&mgr, NULL);
//连接
  c = mg_bind(&mgr, s_http_port, ev_handler);
//http
  mg_set_protocol_http_websocket(c);

  for (;;) {
//mg_mgr_poll()遍历所有套接字,接受新连接,发送和接收数据,关闭连接并为相应事件调用事件处理函数
    mg_mgr_poll(&mgr, 1000);
  }
  mg_mgr_free(&mgr);

  return 0;
}

mg_connect()呼叫建立呼出连接。mg_bind()通话会建立监听连接。入站连接是侦听连接接受的连接。每个连接都由该struct mg_connection 结构描述,该结构具有许多字段,例如套接字,事件处理函数,发送/接收缓冲区,标志等。

ev_handler(事件处理函数)

static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
  switch (ev) {
    /* Event handler code that defines behavior of the connection */
    ...
  }
}
struct mg_connection *nc:已收到事件的连接。
int ev:事件编号,在中定义mongoose.h。例如,当数据到达入站连接时,ev将为MG_EV_RECV。
void *ev_data:此指针指向事件特定的数据,并且对于不同的事件具有不同的含义。例如,对于一个MG_EV_RECV事件,它 ev_data是一个int *指针,指向从远程对等方接收并保存到接收IO缓冲区中的字节数。ev_data针对每个事件描述了的确切含义 。协议特定的事件通常 ev_data指向保存协议特定信息的结构。
注意:struct mg_connection具有void *user_data用于特定于应用程序的数据的占位符。mongoose不使用该指针。事件处理程序可以在其中存储任何类型的信息。

常用函数

mg_send_head
//发送标头     
mg_send_head(struct mg_connection *c, int status_code,
                  int64_t content_length, const char *extra_headers)                  
mg_printf
//发送字符串
mg_printf(struct mg_connection *conn, const char *fmt, ...)
mg_send_http_chunk
mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len)

使用分块HTTP编码buf将大小大小的缓冲区发送len到客户端。此函数首先以十六进制数字+换行符的形式发送缓冲区大小,然后是缓冲区本身,然后是换行符。

例如, mg_send_http_chunk(nc, "foo", 3)3\r\nfoo\r\n字符串附加到nc->send_mbuf输出IO缓冲区。

注意:在使用此功能之前,应发送HTTP标头“ Transfer-Encoding:chunked”。

注意:不要忘记在响应的末尾发送一个空块,以告知客户端所有内容均已发送。

mg_printf_http_chunk(nc, "%s", "my response!");
mg_send_http_chunk(nc, "", 0); // Tell the client we're finished
mg_printf_http_chunk
//发送一个printf格式的HTTP块。功能类似于mg_send_http_chunk()
mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...)

客户端

http_client_example

#include "mongoose.h"

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

static void ev_handler(struct mg_connection *c, int ev, void *p) {
  if (ev == MG_EV_HTTP_REPLY) {
    struct http_message *hm = (struct http_message *)p;
    c->flags |= MG_F_CLOSE_IMMEDIATELY;
    //同理,hm->message.len, hm->message.p存放着服务端发送过来的信息,包括post,Host(http地址),Content-Length(信息的长度),以及信息本身。
    //通过std::string rsp = std::string(hm->body.p, hm->body.len);
    fwrite(hm->message.p, 1, (int)hm->message.len, stdout);
    putchar('\n');
    exit_flag = 1;
  } else if (ev == MG_EV_CLOSE) {
    exit_flag = 1;
  };
}

int main(void) {
  struct mg_mgr mgr;

  mg_mgr_init(&mgr, NULL);
  
  mg_connect_http(&mgr, ev_handler, url, NULL, NULL);


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

  return 0;
}

mg_connect_http

mg_connect_http(struct mg_mgr *mgr,
                                      mg_event_handler_t ev_handler,
                                      const char *url,
                                      const char *extra_headers,
                                      const char *post_data)

值得注意的是 post_data为发送给服务端的信息

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
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` 函数来处理它。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值