mongoose框架示例代码解析(一)

mongoose框架示例代码解析(一)


参考:

  1. Mongoose Networking Library Documentation(Server)
  2. Mongoose Networking Library Documentation(Client)

前言:

OK,感谢完恩公,来看看今天的正文吧~对了,把昨天写时隔九年重新遇到半个初恋的博客置顶一下,时刻给自己一些刺激。这里也放个链接,没错,皮这一下我很快乐!初步了解mac下C源码的编译过程_qq_31433709的博客-CSDN博客

不得不说,起名字真的是一门学问,这两个源文件的方法名还有参数名称都堪称完美一目了然!

说起来,我vim上的C环境都还没有弄呢,这撸代码的过程感觉真的不够快乐!晚上顺便搞定吧!如果没有找到(虽然这个相当不现实),那就顺便学学怎么编写插件吧= =!


正文

一. 服务器端:

源码文件:simplest_web_server.c

// Copyright (c) 2015 Cesanta Software Limited
// All rights reserved

#include "mongoose.h"

static const char *s_http_port = "8000";
static struct mg_serve_http_opts s_http_server_opts;

static void ev_handler(struct mg_connection *nc, int ev, void *p) {
  if (ev == MG_EV_HTTP_REQUEST) {
    mg_serve_http(nc, (struct http_message *) p, s_http_server_opts);
  }
}

int main(void) {
  struct mg_mgr mgr;
  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
  mg_set_protocol_http_websocket(nc);
  s_http_server_opts.document_root = ".";  // Serve current directory
  s_http_server_opts.enable_directory_listing = "yes";

  for (;;) {
    mg_mgr_poll(&mgr, 1000);
  }
  mg_mgr_free(&mgr);

  return 0;
}

(1)先初步扫一眼:

呜呜,好多已经被封进框架的方法调用,常量和结构体:

  1. 结构体:
  • mg_mgr
  • mg_connection
  • mg_serve_http_opts
  1. 方法调用:
  • mg_mgr_init
  • mg_bind
  • mg_serve_http
  • mg_set_protocol_http_websocket
  • mg_mgr_pool
  • mg_mgr_free
  1. 常量:
  • MG_EV_HTTP_REQUEST

只导入了一个头文件,去这里面找找呗= =,哇,6277行,ok,小朋友,你是不是有很多疑问?
头文件中能获取到的我感觉最多只有常量,而方法的实现和结构体的定义,我还是感觉要从.c文件中去获取。

(2)那就先看看头文件吧

vim全局搜一下,MG_EV_HTTP_REQUEST的结果,找到定义就行了,其余的嘛,本来想也列出来,不过为了篇幅的简约,还是省略比较好,个人感觉(大概瞄了一下~),然后我发现无论是结构体还是方法调用抑或是常量,在头文件里面都有很具体的讲解,甚至有示例代码,所以建议直接在mongoose.h文件中自行搜索,然后对于mg_mgr_pool的1000参数,还是需要看.c文件中的具体实现

然后这是我大体理了一圈的结果,毕竟是第一次写这方面的内容,差是差了点,不过毕竟是为了自我的提升(自我安慰),总有从差到好的过程嘛!

// Copyright (c) 2015 Cesanta Software Limited
// All rights reserved

//导入mongoose所依赖的必须头文件
#include "mongoose.h"

//指定默认的服务器http端口号
static const char *s_http_port = "8000";
//指定http链接的各种选项
static struct mg_serve_http_opts s_http_server_opts;

//ev_handler指定的event handler,即事件处理,mg指代的是mongoose
static void ev_handler(struct mg_connection *nc, int ev, void *p) {
  if (ev == MG_EV_HTTP_REQUEST) {
    mg_serve_http(nc, (struct http_message *) p, s_http_server_opts);
  }
}

//总入口,一切的开始
int main(void) {
  struct mg_mgr mgr;
  struct mg_connection *nc;

  //初始化mg_mar变量
  mg_mgr_init(&mgr, NULL);
  printf("Starting web server on port %s\n", s_http_port);
  //这里有点函数式的感觉,传入的不是对象,而是方法指针
  //将mgr和其中的mgr_connection以及对应的端口号还有对应的不同event的处理器所绑定,并返回对应的绑定后的mg_connection对象
  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
  mg_set_protocol_http_websocket(nc);
  //设置客户端访问服务器的初始路径,这里设置为"."即为可执行文件的当前路径
  s_http_server_opts.document_root = ".";  // Serve current directory
  //同时设置是否支持显示当前目录下的文件信息
  s_http_server_opts.enable_directory_listing = "yes";

  for (;;) {
    //这里的1000是什么意思呢?
    //翻译一下文档中对这个方法的描述:
    //这个方法执行实际上的IO操作并且必须在一个循环中被调用(一个事件循环)。
    //它返回了生成的用户事件数目(除了POLL)。
    //第二个参数是以毫秒为单位的睡眠最大时间。
    //该方法为IO操作检查了所有的连接(connection)。如果至少有一个连接已经准备好IO操作,此方法将切换到对应的事件处理器然后返回。
    mg_mgr_poll(&mgr, 1000);
    //所以说,1000到底是什么意思?看来光看头文件比较难啊。
    //ok,大概看了看实现,1000是设置的请求超时时间
  }
  //解构mg_mgr,该方法中应该同时解构了mg_connection,并释放了对应占用的内存,道理的确是这样,但是什么情况下会跳出这个死循环呢?如果我直接通过信号,貌似不会走这步,并没有看见输出stopped的信息
  mg_mgr_free(&mgr);
    printf("stopped mongoose server");
  return 0;
}


小结:

OK,感觉今天看到这个程序差不多了,也适当看到了一些细节,服务端的流程也基本理了一圈了。早睡早起身体好~

发布了306 篇原创文章 · 获赞 26 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_31433709/article/details/105352282
今日推荐