libevent网络通信常用函数

虽然libevent库提供了很多函数,但是使用libevent实现网络socket通信,使用到的函数不多,根据上一篇博客中的代码,我们可以发现,用到函数只有创建event_base结构体的函数,创建事件并绑定事件到event_base中的函数,添加事件到结构体的函数,启用循环的函数等,下面详细说一下这几个函数:

创建 event_base

使用 libevent 函数之前需要分配一个或者多个 event_base 结构体。每个 event_base 结构体持有一个事件集合,可以检测以确定哪个事件是激活的。event_base_new()函数分配并且返回一个新的具有默认设置的 event_base。函数会检测环境变量,返回一个到 event_base 的指针。如果发生错误,则返回 NULL。函数声明在<event2/event.h>中。

创建事件

使用 event_new()接口创建事件。struct event *event_new (struct event_base *base,evutil_socket_t fd,short what,event_callback_fn cb,void *arg);event_new()试图分配和构造一个用于 base 的新的事件。what 参数是上述标志的集合。如果 fd 非负,则它是将被观察其读写事件的文件。事件被激活时,libevent 将调用 cb 函数,传递这些参数:文件描述符 fd,表示所有被触发事件的位字段,以及构造事件时的 arg 参数。发生内部错误,或者传入无效参数时,event_new()将返回 NULL。
所有新创建的事件都处于已初始化和非未决状态,调用 event_add()可以使其成为未决的。event_add(base,NULL);要释放事件,调用 event_free()。对未决或者激活状态的事件调用 event_free()是安全的:在释放事件之前,函数将会使事件成为非激活和非未决的。
事件标志

  • EV_TIMEOUT
    这个标志表示某超时时间流逝后事件成为激活的。构造事件的时候,EV_TIMEOUT 标志是
    被忽略的:可以在添加事件的时候设置超时,也可以不设置。超时发生时,回调函数的 what
    参数将带有这个标志。

  • EV_READ
    表示指定的文件描述符已经就绪,可以读取的时候,事件将成为激活的。

  • EV_WRITE
    表示指定的文件描述符已经就绪,可以写入的时候,事件将成为激活的。

  • EV_SIGNAL
    用于实现信号检测,请看下面的“构造信号事件”节。

  • EV_PERSIST
    表示事件是“持久的”,请看下面的“关于事件持久性”节。

  • EV_ET
    表示如果底层的 event_base 后端支持边沿触发事件,则事件应该是边沿触发的。这个标志
    影响 EV_READ 和 EV_WRITE 的语义。

运行循环

旦有了一个已经注册了某些事件的 event_base就需要让 libevent 等待事件并且通知事件的发生。
int event_base_loop(struct event_base *base,int flags)
默认情况下,event_base_loop()函数运行 event_base 直到其中没有已经注册的事件为止。执行循环的时候,函数重复地检查是否有任何已经注册的事件被触发(比如说,读事件的文件描述符已经就绪,可以读取了;或者超时事件的超时时间即将到达)。如果有事件被触发,函数标记被触发的事件为“激活的”,并且执行这些事件。
在 flags 参数中设置一个或者多个标志就可以改变 event_base_loop()的行为。如果设置了 EVLOOP_ONCE,循环将等待某些事件成为激活的,执行激活的事件直到没有更多的事件可以执行,然会返回。如果设置了 EVLOOP_NONBLOCK,循环不会等待事件被触发:循环将仅仅检测是否有事件已经就绪,可以立即触发,如果有,则执行事件的回调。
完成工作后,如果正常退出,event_base_loop()返回0;如果因为后端中的某些未处理错误而退出,则返回-1。
使用int event_base_dispatch(struct event_base *base)只需一个参数,相对简单一点。
event_base_dispatch ( ) 等 同 于 没 有 设 置 标 志 的 event_base_loop ( )。 所 以 ,event_base_dispatch ()将一直运行,直到没有已经注册的事件了,或者调用 了event_base_loopbreak()或者 event_base_loopexit()为止。

停止循环

int event_base_loopbreak(struct event_base *base,const struct timeval *tv);

int event_base_loopexit(struct event_base *base)
event_base_loopexit()让 event_base 在给定时间之后停止循环。如果 tv 参数为 NULL,event_base 会立即停止循环,没有延时。如果 event_base 当前正在执行任何激活事件的回调,则回调会继续运行,直到运行完所有激活事件的回调之才退出。event_base_loopbreak ( ) 让 event_base 立 即 退 出 循 环 。 它 与 event_base_loopexit(base,NULL)的不同在于,如果 event_base 当前正在执行激活事件的回调,它将在执行完当前正在处理的事件后立即退出。注意event_base_loopexit(base,NULL)和 event_base_loopbreak(base)在事件循环没有运行时的行为不同:前者安排下一次事件循环在下一轮回调完成后立即停止(就好像 带EVLOOP_ONCE 标志调用一样);后者却仅仅停止当前正在运行的循环,如果事件循环没有运行,则没有任何效果。这两个函数都在成功时返回0,失败时返回-1。有时候需要知道对 event_base_dispatch()或者 event_base_loop()的调用是正常退出的,还是因为调用 event_base_loopexit()或者 event_base_break()而退出的。可以调用下述函数来确定是否调用了 loopexit 或者 break 函数.
int event_base_got_exit(struct event_base *base);
int event_base_got_break(struct event_base *base);

以上这些就是实现网络通信时用到的几个函数,需要用到其它的函数,可以搜索自己学习。很多时候,除了响应事件之外,应用还希望做一定的数据缓冲。libevent 为此提供了一种通用机制,即 bufferevent。这个正在学习当中,还不是很懂,就先不写了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值