libevent中的bufferevent

bufferevent是libevent中处理网络事件很重要也是比较复杂的一个模块,其中包含一个读事件,一个写事件,两个缓冲区(读和写)、读写水位、三个回调(读、写、出错)和函数指针组成的操作集。目前支持的操作集有五种:基于socket的,基于pair的,基于过滤的及基于SSL,异步(WIN32 iocp)的五种。bufferevent的结构为

struct bufferevent {
    /** Event base for which this bufferevent was created. */
    struct event_base *ev_base;
    /** Pointer to a table of function pointers to set up how this
        bufferevent behaves. */
    const struct bufferevent_ops *be_ops;  //操作集

    /** A read event that triggers when a timeout has happened or a socket
        is ready to read data.  Only used by some subtypes of
        bufferevent. */
    struct event ev_read;  //读事件
    /** A write event that triggers when a timeout has happened or a socket
        is ready to write data.  Only used by some subtypes of
        bufferevent. */
    struct event ev_write;  //写事件

    /** An input buffer. Only the bufferevent is allowed to add data to
        this buffer, though the user is allowed to drain it. */
    struct evbuffer *input;   //输入缓冲区

    /** An input buffer. Only the bufferevent is allowed to drain data
        from this buffer, though the user is allowed to add it. */
    struct evbuffer *output;        //输出缓冲区

    struct event_watermark wm_read;  //读操作的水位
    struct event_watermark wm_write;    //写操作的水位

    bufferevent_data_cb readcb;    //用于应用层读操作的回调
    bufferevent_data_cb writecb;    //用于应用层写操作的回调
    /* This should be called 'eventcb', but renaming it would break
     * backward compatibility */
    bufferevent_event_cb errorcb;   //出错时的回调
    void *cbarg;

    struct timeval timeout_read;
    struct timeval timeout_write;

    /** Events that are currently enabled: currently EV_READ and EV_WRITE
        are supported. */
    short enabled;
};

1. bufferevent的选项
bufferevent有四种选项:
BEV_OPT_CLOSE_ON_FREE:释放缓冲区时关闭socket描述符
BEV_OPT_THREADSAFE:开启线程情况下,bufferevent由锁来同步
BEV_OPT_DEFER_CALLBACKS:回调添加到event_base中的回调,由event_base事件循环来处理
BEV_OPT_UNLOCK_CALLBACKS:无锁回调,这个选项需要与BEV_OPT_DEFER_CALLBACKS一起使用。
2. bufferevent中的水位
bufferevent中读操作的低水位是用于应用层读,如果输入缓冲区的数据长度大于低水位,则调用应用层的读回调,而高水位是用于控制socket I/O的读操作,如果输入缓冲区的数据长度大于高水位,就将删除socket的读事件,即不将socket中的数据读入输入缓冲区中。而写操作的低水位,如果输出缓冲区的数据长度小于低水位则调用应用层的写操作,将数据写入输入缓冲区中,而针对socket,syn,pair,ssl,filter这几种bufferevent操作有不同的含义。
3. 读写事件的开启关闭
设置水位后,读写事件的开启关闭是根据水位来动态调节,其函数为

void bufferevent_suspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what)
void bufferevent_unsuspend_read(struct bufferevent *bufev, bufferevent_suspend_flags what)
void bufferevent_suspend_write(struct bufferevent *bufev, bufferevent_suspend_flags what)
void bufferevent_unsuspend_write(struct bufferevent *bufev, bufferevent_suspend_flags what)

4. 应用层事件的回调
应用层事件的回调分为延时的和无延时的的。延时回调是在设置了BEV_OPT_DEFER_CALLBACKS属性后,事件放在event_base事件循环中来处理的。其相应的函数为

void bufferevent_run_deferred_callbacks_locked(struct deferred_cb *_, void *arg)  
void bufferevent_run_deferred_callbacks_unlocked(struct deferred_cb *_, void *arg)
void _bufferevent_run_readcb(struct bufferevent *bufev)
void _bufferevent_run_writecb(struct bufferevent *bufev)
void _bufferevent_run_eventcb(struct bufferevent *bufev, short what)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
libeventbufferevent 可以用于收发数据,具体步骤如下: 1. 创建 bufferevent 对象: ``` struct bufferevent *bev; bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE); ``` 其,base 是 event_base 对象,fd 是已连接的 socket 文件描述符,BEV_OPT_CLOSE_ON_FREE 表示在释放 bufferevent 对象时关闭底层的 socket 连接。 2. 设置回调函数: ``` void bev_read_cb(struct bufferevent *bev, void *ctx) { // 处理读事件 } void bev_write_cb(struct bufferevent *bev, void *ctx) { // 处理写事件 } void bev_event_cb(struct bufferevent *bev, short events, void *ctx) { // 处理事件 } bufferevent_setcb(bev, bev_read_cb, bev_write_cb, bev_event_cb, NULL); ``` bufferevent_setcb 函数用于设置 bufferevent 对象的回调函数,包括读、写、事件回调函数。 3. 启用 bufferevent: ``` bufferevent_enable(bev, EV_READ|EV_WRITE); ``` bufferevent_enable 函数用于启用 bufferevent 对象的读写事件。 4. 发送数据: ``` const char *data = "hello, world"; bufferevent_write(bev, data, strlen(data)); ``` bufferevent_write 函数用于向 bufferevent 对象写入数据。 5. 接收数据: ``` void bev_read_cb(struct bufferevent *bev, void *ctx) { char buf[1024]; size_t len = bufferevent_read(bev, buf, sizeof(buf)); // 处理接收到的数据 } ``` bev_read_cb 回调函数,使用 bufferevent_read 函数从 bufferevent 对象读取数据。 以上就是 libeventbufferevent 收发数据的基本步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值