赞
踩
bufferevent由一个底层的传输端口(如套接字),一个读取缓冲区和一个写入缓冲区组成。与通常的事件在底层传输端口已经就绪,可以读取或者写入的时候执行回调不同的是,bufferevent在读取或者写入了足够量的数据之后调用用户提供的回调。
基于套接字的bufferevent是最简单的,它使用libevent的底层事件机制来检测底层网络套接字是否已经就绪,可以进行读写操作,并且使用底层网络调用(如readv、writev、WSASend、WSARecv)来发送和接收数据。
创建基于套接字的bufferevent,将需要监听的文件描述符fd添加到事件集合base中去。
struct bufferevent * bufferevent_socket_new(
struct event_base *base,
evutil_socket_t fd,
enum bufferevent_options options
);
返回值:
成功:返回一个指向结构体bufferevent的指针,失败则返回NULL
bufferevent也是一个event
base是event_base。
fd是一个可选的表示套接字的文件描述符。如果是socket的方法,则socket需要设置为非阻塞模式(在socket()和bind()之间)。如果想以后设置文件描述符,可以设置fd为-1。
options是表示bufferevent选项标志的位掩码。
bufferevent的选项标志:
标志 | 含义 |
---|---|
BEV_OPT_CLOSE_ON_FREE | 释放bufferevent时关闭底层传输端口。这将关闭底层套接字(socket被关闭等),释放底层bufferevent等(一般用这个选项) |
BEV_OPT_THREADSAFE | 自动为bufferevent分配锁,这样就可以安全地在多个线程中使用bufferevent |
BEV_OPT_DEFER_CALLBACKS | 设置这个标志时,bufferevent延迟所有回调,参考时延回调 |
BEV_OPT_UNLOCK_CALLBACKS | 默认情况下,如果设置bufferevent为线程安全的,则bufferevent会在调用用户提供的回调时进行锁定。设置这个选项会让libevent在执行回调的时候释放bufferevnt的锁 |
void bufferevent_free(struct bufferevent *bev);
这个函数释放bufferevent。
bufferevent内部具有引用计数,所以,如果释放bufferevent时还有未决的延迟回调,则在回调完成之前bufferevent不会被删除。
例子:
如果设置了延时回调BEV_OPT_UNLOCK_CALLBACKS,则释放会在延时回调调用了回调函数之后,才会真正释放。
如果设置了BEV_OPT_CLOSE_ON_FREE标志,并且bufferevent有一个套接字或者底层bufferevent作为其传输端口,则释放bufferevent将关闭这个传输端口。
如果bufferevent的套接字还没有连接上,可以启动新的连接。
接口:
//如果连接启动成功,函数返回0;发生错误则返回-1
int bufferevent_socket_connect(
struct bufferevent *bev,
struct sockaddr *address, int addrlen);
address和addrlen参数跟标准调用connect()的参数相同。
如果还没有为bufferevent设置套接字,调用函数将为其分配一个新的流套接字,并且设置为非阻塞的。
如果已经为bufferevent设置套接字,调用bufferevent_socket_connect()将告知libevent套接字还未连接,直到连接成功之前不应该对套接字进行读取或者写入操作。
连接完成之前可以向输出缓冲区添加数据。
使用bufferevent之后,libevent会帮我们托管三种事件:
1、读取事件
2、写入事件
3、处理事件
这三种事件都在回调的函数结构中体现!!
//对bufferevent设置回调函数
void bufferevent_setcb(
struct bufferevent *bufev,
bufferevent_data_cb readcb, //读取足够的数据时被调用
bufferevent_data_cb writecb, //写入足够的数据时被调用
bufferevent_event_cb eventcb,
void *cbarg //共用的传入回调函数的参数
);
//读取和写入的回调,其中ctx为通用传递的参数
typedef void (*bufferevent_data_cb)(
struct bufferevent *bev,
void *ctx
);
//事件回调,即连接断开、错误处理等回调
typedef void (*bufferevent_event_cb)(
struct bufferevent *bev,
short events,
void *ctx
);
event参数为事件,用户可以在回调函数中拿这个事件来进行事务处理的判断
events参数 | 作用 |
---|---|
BEV_EVENT_READING | 在bufferevent上进行读取操作时出现了一个事件 |
BEV_EVENT_WRITING | 在bufferevent上进行写入操作时发生了一个事件 |
BEV_EVENT_ERROR | 在bufferevent上操作时发生错误 |
BEV_EVENT_TIMEOU | 在bufferevent上发生超时 |
BEV_EVENT_EOF | 在bufferevent上遇到文件结束符,连接断开 |
BEV_EVENT_CONNECTED | 在bufferevent上请求的连接过程已经完成(实现客户端的时候可以判断) |
设置回调函数为启动状态或禁用态:
可以启用或者禁用 bufferevent 上的 EV_READ、EV_WRITE 或者 EV_READ | EV_WRITE 事件。没有启用读取或者写入事件时, bufferevent 将不会试图进行数据读取或者写入。
//开启 void bufferevent_enable( struct bufferevent *bufev, short events ); //禁用, 对应的回调就不会被调用 void bufferevent_disable( struct bufferevent *bufev, short events ); short bufferevent_get_enabled( struct bufferevent *bufev );
int bufferevent_write(
struct bufferevent *bufev,
const void *data,
size_t size
//返回值:成功0,失败-1
);
int bufferevent_write_buffer(
struct bufferevent* bufev,
struct evbuffer* buf);
bufferevent_write()从bufferevent的输出缓冲区添加(写)数据
将内存中从data处开始的size字节数据添加到输出缓冲区的末尾
bufferevent_write_buffer()移除buf的所有内容,将其放置到输出缓冲区的末尾。
这些函数:成功返回0,发生错误时则返回-1。
size_t bufferevent_read(
struct bufferevent *bufev,
void *data,
size_t size
);
int bufferevent_read_buffer(
struct bufferevent* bufev,
struct evbuffer* buf)
bufferevent_read()从bufferevent的输入缓冲区移除(读)数据
至多从输入缓冲区移除size字节的数据,将其存储到内存中data处。
返回值:实际移除的字节数。
注意,data处的内存块必须有足够的空间容纳size字节数据。
bufferevent_read_buffer()函数抽空输入缓冲区的所有内容,将其放置到buf中
这些函数:成功时返回0,失败时返回-1。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。