Libevent 学习十一:bufferevent filter 过滤器和API

bufferevent filter 过滤器简介

bufferevent filter 过滤器可以在 读取前和写入后对数据进行一系列的预处理操作,比如压缩和加密。对用户来讲,过滤器就像一个黑盒子,用户仍然只需要完成读取和写入,而不必知晓过滤器中的操作。bufferevent filter 的数据流如下图:

在这里插入图片描述

underlying bufferevent 表示潜在的、根本的 bufferevent,即用户处理读写操作的 bufferevent,而 filter bufferevent 是在此基础上创建的,后面的代码会有详细说明。读取和写入(接收和发送)的数据流刚好相反:

  • 读取(接收)的数据先进入过滤器中,在过滤器处理完成后再传递给用户进行读取,即 过滤在读取之前 ,例如压缩数据要先在 filter 中解压,然后在 underlying 读取解压后的原始;
  • 写入(发送)的数据由用户发起,再传给过滤器,过滤器处理完后再发送出去,即 过滤在写入之后 ,例如在 underlying 中发送的原始数据,会在 filter 中进行压缩后再发送。

bufferevent filter 过滤器 API 分析

要使用过滤器,需要先明白 bufferevent_filter_new 函数和结构体 evbuffer

  • bufferevent_filter_new 函数定义

    struct bufferevent *
    bufferevent_filter_new(struct bufferevent *underlying,
                           bufferevent_filter_cb input_filter,
                           bufferevent_filter_cb output_filter,
                           int options,
                           void (*free_context)(void *),
                           void *ctx);
    

    回调函数 bufferevent_filter_cb 的定义如下

    /**
     * @brief: 回调函数,用于实现 bufferevent 的过滤器
     *
     * @param src: 源事件缓存
     * @param dst: 目的事件缓存
     * @param dst_limit: 写入 dst 的字节上限,-1表示无限制
     * @param mode: 数据刷新模式
     * @param ctx: 用户传递的参数
     *
     * @return: 返回过滤器的处理结果,详见后面说明
     */
    typedef enum bufferevent_filter_result (*bufferevent_filter_cb)(
        struct evbuffer *src, struct evbuffer *dst, 
        ev_ssize_t dst_limit, enum bufferevent_flush_mode mode, void *ctx);
    
    // filter 回调函数返回值
    enum bufferevent_filter_result {
    	// 正常
    	BEV_OK = 0,
    	// 还需要更多的数据才能输出
    	BEV_NEED_MORE = 1,
    	// filter 发生错误,无法进一步处理数据
    	BEV_ERROR = 2
    };
    
    // filter 数据刷新模式
    enum bufferevent_flush_mode {
    	// 正常处理数据
    	BEV_NORMAL = 0,
    	// 检查发送的所有数据
    	BEV_FLUSH = 1,
    	// 读完或写完数据后,会有 EOF 标志
    	BEV_FINISHED = 2
    };
    
  • evbuffer 是一个不透明的结构体,即只有声明,定义不对外公开,用于在 bufferevent 上发送或接收的数据,其实这个结构体就是在 filter bufferevent 和 underlying bufferevent 之间传递数据用的。在过滤器中,常用的与之相关的函数有 evbuffer_addevbuffer_remove ,分别表示在 evbuffer 中添加数据和读取数据,函数定义如下

    /**
     * @breif: 添加数据到 evbuffer 的结尾处
     *
     * @param buf: 待添加数据的 evbuffer 对象
     * @param data: 数据指针
     * @param datlen: 数据长度,单位 byte
     *
     * @return: 成功返回0,失败返回-1
     */
    int evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen);
    
    /**
     * @brief: 从 evbuffer 的开始处读取指定长度的数据
     *         若 evbuffer 中的数据不足指定长度,则尽可能多的读取数据
     *
     * @param buf: 待读取数据的 evbuffer 对象
     * @param data: 数据指针
     * @param datlen: 数据长度,单位 byte
     *
     * @return: 成功返回读取的字节数,失败返回-1
     */
    int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen);
    

    简单来说,evbuffer_add 类似向队尾插入数据,evbuffer_remove 类似从队头读取数据。事实上它内部就是链表实现的,我在网上收到一位大神画的 evbuffer 结构体图,在此膜拜一下here

在这里插入图片描述

buffervent 和 evbuffer 经常一起使用,但也有区别

  • bufferevent 是一个事件缓冲 I/O,内部实现了基本 socket recv/send 操作;
  • evbuffer 只是一个数据缓冲区,使用链表实现,不带任何 I/O 操作。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值