系列文章回顾

  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;
}

libevent学习之入门--[02]从hello-world开始的更多相关文章

  1. 【网络爬虫入门02】HTTP客户端库Requests的基本原理与基础应用

    [网络爬虫入门02]HTTP客户端库Requests的基本原理与基础应用 广东职业技术学院  欧浩源 1.引言 实现网络爬虫的第一步就是要建立网络连接并向服务器或网页等网络资源发起请求.urllib是 ...

  2. CSS3基础入门02

    CSS3 基础入门02 边框相关属性 border-radius 通过这个属性我们可以设置边框圆角,即可以将四个角设置为统一的圆角,也可以单独的设置具体的某一个角的圆角. grammer: borde ...

  3. Java工程师学习指南 入门篇

    Java工程师学习指南 入门篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都 ...

  4. 093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 02 static关键字 03 static关键字(下)

    093 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  5. 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 02 封装的代码实现

    088 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 02 封装的代码实现 本文知识点:Java封装的代码实现 说明:因为时间紧张,本人写博客过程中只 ...

  6. 080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则

    080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则 本文知识点:单一职责原则 说明:因为时间紧张,本人写博客过程中只是 ...

  7. Python学习--01入门

    Python学习--01入门 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.和PHP一样,它是后端开发语言. 如果有C语言.PHP语言.JAVA语言等其中一种语言的基础,学习Py ...

  8. [IT学习]sql 入门及实例

    sql 是一种数据库查询语言,可以让你很快的查询到数据.其实一般情况下,你也可以采用excel来查询数据库数据. 但是人们通常认为sql会更加灵活和方便一些. sql学习的入门网站: http://w ...

  9. PHP学习笔记 - 入门篇(5)

    PHP学习笔记 - 入门篇(5) 语言结构语句 顺序结构 eg: <?php $shoesPrice = 49; //鞋子单价 $shoesNum = 1; //鞋子数量 $shoesMoney ...

  10. PHP学习笔记 - 入门篇(4)

    PHP学习笔记 - 入门篇(4) 什么是运算符 PHP运算符一般分为算术运算符.赋值运算符.比较运算符.三元运算符.逻辑运算符.字符串连接运算符.错误控制运算符. PHP中的算术运算符 算术运算符主要 ...

随机推荐

  1. vue+vant打包,vue+vant-ui小程序,微信支付

    微信JS支付代码_前端调用微信支付接口 其实参照官方文档一步一步操作不是很难,但很多人在签名这个地方就总是出现问题,因为文档中签名时使用的字段大小写时错误的....好坑啊!!然而PHP版本的代码官方有 ...

  2. mysql 优化表空间报错Creating index 'PRIMARY' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again

    背景:mysql数据库中有几个表的碎片率太高,浪费了存储空间且降低了读写效率,需要整理. mysql版本:5.6 先用optimize table 试试. 也执行了很久.但是结束后,data_free ...

  3. hooks组件中,使用防抖节流的方法。

    在类组件中,使用节流函数可以在componentDidMount中定义. 而在hooks函数中,该怎么定义呢,我们一起看看. 要使用useCallback包起来,返回一个记忆的缓存函数,这样才能达到节 ...

  4. nvm node 版本管理

    nvm安装与使用 1.nvm是什么 nvm全名node.js version management,顾名思义是一个nodejs的版本管理工具.通过它可以安装和切换不同版本的nodejs.下面列出下载. ...

  5. Arch安装记录(BIOS+GPT)

    尝试了下arch安装,并且尝试了下不长用的BIOS + GPT组合.都说arch的wiki强,确实很强,可惜自己的水平看不了多少. https://wiki.archlinux.org/index.p ...

  6. Linux LVM分区相关知识

    Linux分区有多种方式,一种是LVM格式的比较方便,另一种是标准分区扩容比较麻烦,麻烦的事情那么出错的概率也就越大,所以建议生产环境上分区都使用LVM格式硬盘分区. 一.    什么叫LVM?  L ...

  7. GPT-3介绍

    参考:https://en.wikipedia.org/wiki/GPT-3 Generative Pre-trained Transformer 3(GPT-3)是一个自回归语言模型,于2020年发 ...

  8. python IDLE清除窗口内容和new file里代码加行业的操作

    这个其实比较简单,主要是从网上下载好ClearWindow.py这个文件,然后把文件放到./Lib/idlelib下面,同时打开该文件夹下config-extensions.def文件,在文件尾加入下 ...

  9. 火爆全球的“饺子皮”3D手办原来是这样做的!关键时刻少不了远程控制软件!

    2022年卡塔尔世界杯的吉祥物最近在全球火出圈了,并且喜提中国网友给予的爱称"饺子皮"."馄饨皮"(官方名字:拉伊卜,意为"技艺高超的球员" ...

  10. 通过if 简单判断奇数偶数

    方法一 方法二 方法三 通过取反的方式进行 其实这三个方法都差别不大都可以用