Libevent 学习八:bufferevent 基础概念

bufferevent 基础概念

本章介绍 Libevent 中一个比较高级的概念 bufferevent
bufferevent 是 Libevent 中的一个事件缓冲 IO,内部实现了基本 socket recv/send 操作 ,用户只需要调用 bufferevent 的 API 即可实现数据的读写,而传统的 Libevent 使用方式则需要用户读写 socket,相对而言,bufferevent 更加方便。个人觉得,没有 asio 中的异步调用方便,可能是 C 语言实现的缘故吧,但也值得学习。

bufferevent 的结构体位于 <event2/bufferevent_struct.h> 文件中,定义如下:

struct bufferevent {
    // 创建 bufferevent 的 event_base 对象
    struct event_base *ev_base;

    // 操作结构体,内部是一些函数指针,类似 struct eventop 结构体
    const struct bufferevent_ops *be_ops;

    // 读事件
    struct event ev_read;
    // 写事件
    struct event ev_write;

    // 读缓冲区,即输入缓冲区
    struct evbuffer *input;
    // 写缓冲区,即输出缓冲区
    struct evbuffer *output;

    // 读水位和写水位
    struct event_watermark wm_read;
    struct event_watermark wm_write;

    // 数据可读回调函数
    bufferevent_data_cb readcb;
    // 数据可写回调函数
    bufferevent_data_cb writecb;
    // 发生错误的回调函数
    bufferevent_event_cb errorcb;
    // 回调参数,与上面3个回调函数配合使用
    void *cbarg;

    // 读写事件的超时时间,默认设为0
    struct timeval timeout_read;
    struct timeval timeout_write;

    // 事件使能标志,目前只支持 EV_READ 和 EV_WRITE
    short enabled;
};

bufferevent 的结构如下所示:

在这里插入图片描述

bufferevent 中的一些基础概念:

  • 缓冲区:每个 bufferevent 都有一个读缓冲区(input)和写缓冲区(output),数据结构为 evbuffer ,它是一个数据缓冲区,用于缓存网络上发送或接收的数据。也是一个不透明的数据类型,即结构体的定义位于 Libevent 内部,只能通过 API 来操作,看不到具体定义,当然,用户也不必关心它的定义。

  • 回调和水位:回调与基础的 event 类似,也分为读取回调、写入回调和事件回调,回调函数的定义如下:

    // 读取和写入回调
    typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);
    
    // 事件回调,其中what表示发生的事件,具体后面有说明
    typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short what, void *ctx);
    

    可以通过设置水位来调节回调函数的调用,水位 event_watermark 的定义比较简单,两个 size_t 字段分别表示高低水位,又根据读写不同分为以下 4 类:

    • 读取低水位:输入缓冲区的数据量达到或超过此水位时,调用回调函数,即数据量达不到水位要求,则不会调用回调;
    • 读取高水位:输入缓冲区的数据量达到此水位时,bufferevent 将停止读取,直到输入缓冲区中的数据被读取,使得数据量低于此水位。注意用于限制一次读取的最大数据量。
    • 写入低水位:输出缓冲区中的数据量达到或低于此水位时,写入回调将被调用;
    • 写入高水位:不设置,直接写入即可,一般不用。

    默认情况下,读取低水位和高水位都为 0,表示有数据就读取,且不会限定最大读取数量。写入的水位也是一样,表示可写即会全部写入。

  • 事件回调函数中多了一个 what 参数,表示发生的事件,目前支持的事件定义如下:

    // 读取错误
    #define BEV_EVENT_READING	0x01	/**< error encountered while reading */
    
    // 写入错误
    #define BEV_EVENT_WRITING	0x02	/**< error encountered while writing */
    
    // 到达文件结尾
    #define BEV_EVENT_EOF		0x10	/**< eof file reached */
    
    // 不可恢复的错误
    #define BEV_EVENT_ERROR		0x20	/**< unrecoverable error encountered */
    
    // 到达直到的超时时间
    #define BEV_EVENT_TIMEOUT	0x40	/**< user-specified timeout reached */
    
    // 连接操作完成
    #define BEV_EVENT_CONNECTED	0x80	/**< connect operation finished. */
    

最后,需要说明一点,目前 bufferevent 只支持 TCP 连接,未来可能支持 UDP 连接。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值