系列文章回顾

  libevent学习之入门--[01]概述与安装

  上一节介绍了libevent的下载和编译,从这节开始,我会从我学习的角度逐步探索libevent的源码,慢慢揭开它的神秘面纱。

  面对几十个源文件,很多人都会无从下手,根本不知道跟个源码的层次结构是什么,主要分为哪几个部分,哪些是核心文件,哪些是无关紧要的文件。

  我采用的方法可能是面对这种问题比较好的解决方案,那就是从官方给出的例程入手,窥探出大概的函数调用关系。

  在源代码中有一个文件夹sample,这个文件夹内包含了大量的例程,我们就从亲切的hello-world.c文件入手。

  打开哈喽沃德文件,首先是文件功能说明:

/*
  This example program provides a trivial server program that listens for TCP
  connections on port 9995.  When they arrive, it writes a short message to
  each client connection, and closes each connection once it is flushed.
  Where possible, it exits cleanly in response to a SIGINT (ctrl-c).
*/
大致意思如下:
/*这个示例程序提供了一个简单的服务器程序,它监听端口9995上的TCP连接。
当它们到达时,它会向每个与之连接的客户端写入一条信息,并在刷新后关闭每个连接。
在可能的情况下,它会干净地退出以响应SIGINT(ctrl-c)。
*/

  接着是各种头文件和不同操作系统的预编译,我们全部忽略。继续往下定义了如下全局静态变量和函数:

static const char MESSAGE[] = "Hello, World!\n";
static const int PORT = 9995;
static void listener_cb(struct evconnlistener *, evutil_socket_t, struct sockaddr *, int socklen, void *);
static void conn_writecb(struct bufferevent *, void *);
static void conn_eventcb(struct bufferevent *, short, void *);
static void signal_cb(evutil_socket_t, short, void *);

  可以看出,MESSAGE就是服务器向客户端发送的信息"Hello,World",PORT则是服务器监视的端口9995。后面的四个函数我们暂且先不管,目前还不能确定是什么功能。

  继续往后看,看到了程序入口main函数,这才是我们要分析的入口,开头为一些变量的声明:

struct event_base *base;
struct evconnlistener *listener;
struct event *signal_event;
struct sockaddr_in sin;
#ifdef _WIN32
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
#endif

  从这开始就需要仔细分析了,首先出现了整个程序的四个结构体,可以推断这四个结构体是程序所需要的核心结构体,接着是关于WIN32的条件编译,我们不用管,下面就会对这几个结构体指针进行赋值。

base = event_base_new();
if (!base) {
fprintf(stderr, "Could not initialize libevent!\n");
return 1;
}

  接下来的这段代码对event_base类型的指针进行赋值,赋值过程通过event_base_new函数实现。这时从命名来看,这个base应该就是事件的核心结构,而event_base_new函数则是作为base事件初始化而使用的,这点从下面base初始化失败时的错误信息也可以看出。

  我们分析event_base_new函数,该函数在event.c文件内实现,下面为源码:

struct event_base * event_base_new(void) {
struct event_base *base = NULL;
struct event_config *cfg = event_config_new();
if (cfg) {
base = event_base_new_with_config(cfg);
event_config_free(cfg);
}
return base;
}

最新文章

  1. ACM blockhouses
  2. Photoshop-制作图片圆角2种方法[转]
  3. hdfs[命令] dfsadmin
  4. Swift方法
  5. InnoSetup中枚举出INI文件的所有sections和键值
  6. Struts2 实现文件上传
  7. MyBatis从入门到放弃一:从SqlSession实现增删改查
  8. opencv配置(win10+VS2015+opencv3.1)
  9. angular2 学习笔记 の 移动端开发 ( 手势 )
  10. Android使用Mob ShareSDK 分享不同平台
  11. JavaScript 事件绑定函数
  12. Kubelet bootstrap认证配置步骤
  13. Reading | 《机器学习》(周志华)(未完待续)
  14. kafka脚本
  15. go语言之进阶篇显式调用panic函数
  16. RTX——第14章 信号量
  17. Redis-Java 交互的应用
  18. win下环境变量的设置
  19. Skip-External-Locking – MySQL性能参数详解
  20. 集群中的session共享存储 实现会话保持

热门文章

  1. ubuntu亲测安装opencv和成功解决Makefile:160: recipe for target 'all' failed make: *** [all] Error 2
  2. vue学习之-----组件递归调用
  3. 解决手机点击包含a、button标签时出现背景色问题
  4. Linux常用的操作指令01
  5. PS 查看进行状态
  6. 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的互转 JAVA
  7. docker之安装tomcat
  8. -behaviour()的使用,他具体有什么作用
  9. Java基础__05.网络编程
  10. mysql报错:MySQL server has gone away