文章目录
bufferevent 基础接口
bufferevent 的接口都位于头文件 <event2/bufferevent.h>
中,本章介绍一些常用的接口。
创建 bufferevent 上下文
创建 bufferevent 上下文接口
struct bufferevent *bufferevent_socket_new(
struct event_base *base, evutil_socket_t fd, int options);
参数说明:
-
base :Libevent 上下文;
-
fd :socket 描述符,bufferevent 的读写操作都基于此描述符;
-
options :可选项,定义如下:
enum bufferevent_options { // 释放bufferevent时,关闭底层socket传输 BEV_OPT_CLOSE_ON_FREE = (1<<0), // 线程安全,即在bufferevent中使用lock,此时callback也会被加锁 BEV_OPT_THREADSAFE = (1<<1), // 在事件循环中延迟回调 BEV_OPT_DEFER_CALLBACKS = (1<<2), // 不对回调函数加锁,即便设置了BEV_OPT_THREADSAFE也不加锁 // 此选项需要与BEV_OPT_DEFER_CALLBACKS一起使用,未来可能会移除这一要求 BEV_OPT_UNLOCK_CALLBACKS = (1<<3) };
一般使用 BEV_OPT_CLOSE_ON_FREE 选项较多,表示在 在 bufferevent_free 时也会关闭 socket 。
返回值:创建成功返回 bufferevent 对象,否则返回 NULL。
若在调用 bufferevent_socket_new 时 fd 设为 -1,则函数内部会自动调用 socket(),并设置为 nonblock。
开启/关闭 bufferevent 操作
开启/关闭 bufferevent 操作,一般就是设置或禁用 bufferevent 可读、可写。
// 开启
int bufferevent_enable(struct bufferevent *bufev, short event);
// 关闭
int bufferevent_disable(struct bufferevent *bufev, short event);
参数说明:
- bufev :bufferevent 上下文;
- event :指定使能事件,一般就是读写事件 EV_READ | EV_WRITE;
返回值:成功返回 0,失败返回 -1。
设置 bufferevent 的回调函数
设置 bufferevent 的回调函数包括 read、write、event 三个回调函数。
void bufferevent_setcb(struct bufferevent *bufev,
bufferevent_data_cb readcb, bufferevent_data_cb writecb,
bufferevent_event_cb eventcb, void *cbarg);
参数说明:
- bufev :bufferevent 上下文;
- readcb :读取回调函数;
- writecb :写入回调函数;
- eventcb :事件回调函数,注意事件回调函数比读写回调函数多了一个参数,用于标识发生的事件;
- cbarg :传入回调函数的参数。
读写与事件回调函数前一章已经介绍过,这里再次声明一下:
// 读取和写入回调
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);
// 事件回调,其中what表示发生的事件,具体后面有说明
typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short what, void *ctx);
读取 bufferevent 缓冲区
bufferevent_read 函数可以读取 bufferevent 缓冲区中的数据。
size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size);
参数说明:
- bufev :bufferevent 上下文;
- data :存储数据的缓冲区;
- size :存储数据的缓冲区长度。
返回值:读取数据的长度,单位:bytes 。
写入 bufferevent 缓冲区
bufferevent_write 函数将数据写入 bufferevent 缓冲区。
int bufferevent_write(struct bufferevent *bufev, const void *data, size_t size);
参数说明:
- bufev :bufferevent 上下文;
- data :待写入的数据地址;
- size :待写入的数据长度。
返回值:成功返回 0,失败返回 -1。
设置 bufferevent 超时时间
设置 bufferevent 超时时间,主要是设置读写超时。
int bufferevent_set_timeouts(struct bufferevent *bufev,
const struct timeval *timeout_read, const struct timeval *timeout_write);
参数说明:
- bufev :bufferevent 上下文;
- timeout_read :读超时,NULL 表示不超时;
- timeout_write :写超时,NULL 表示不超时。
返回值:成功返回 0,失败返回 -1。
注意,如果超时时间已过,则相应的操作(EV_READ or EV_WRITE)将被禁用,直到它被再次启用。在 bufferevent 的事件回调函数中,可以使用如下方法判断是否为读写超时
if ((what & BEV_EVENT_TIMEOUT) && (what & BEV_EVENT_READING)) { /* 读超时 */ }
if ((what & BEV_EVENT_TIMEOUT) && (what & BEV_EVENT_WRITING)) { /* 写超时 */ }
释放 bufferevent
释放一个缓存事件(bufferevent)
void bufferevent_free(struct bufferevent *bufev);
参数说明:
- bufev :bufferevent 上下文。
bufferevent_free 函数内部有引用计数,它会尽快的关闭,即在判断没有引用后才会闭关,不会立即关闭。如果设置了 BEV_OPT_CLOSE_ON_FREE
标志,在 bufferevent_free 时也会将 socket 关闭。
另外,需要注意,如果用 bufferevent_write 发送后立马调用 bufferevent_free 可能会导致部分数据没有发出去 ,所以不要过早关闭 bufferevent。
连接服务端 socket
连接服务端 socket ,一般用于客户端程序。
int bufferevent_socket_connect(struct bufferevent *bufev,
const struct sockaddr *addr, int socklen);
参数说明:
- bufev :bufferevent 上下文;
- addr :服务端的 socket 地址;
- socklen :服务端的 socket 地址长度。
bufferevent_socket_connect 是对 socket connect 函数的封装,注意,在调用此函数时,bufferevent 中的 socket fd 必须设置为 nonblock 。正常情况下,若连接成功,会引起 BEV_EVENT_CONNECTED
的事件回调。