Bufferevent
使用bufferevent来实现客户端和服务器+
bufferevent由一个底层的传输接口(套接字),一个读取缓冲区,一个写入缓冲区组成,bufferevent再读取/写入了足够的数据量之后调用用户提供的回调函数(一个读取回调,一个写入回调)
bufferevent的缓冲区类型都是struct evbuffer
1、fferevent的接口:
struct bufferevent* bufferevent_socket_new(
struct event_base* base,
evutil_socket_t fd,
enum bufferevent_options options
);
其中标志及其含义如下:
BEV_OPT_CLOSE_ON_FREE 释放bufferevent时关闭套接字
BEV_OPT_THREADSAFE 为bufferevent分配锁(线程安全)
BEV_OPT_DEFER_CALLBACKS 设置的时候延迟所有的回调
BEV_OPT_UNLOCK_CALLBACKS 线程安全时会在调用回调的时候上锁,设置这个标志不会上锁
2、在bufferevent上面启动连接
int bufferevent_socket_connect(
struct bufferevent bev,
struct sockaddr ddress,
int addrlen
);
3、释放bufferevent
void bufferevent_free(struct bufferevent* bev);
4、回调函数
设置回调函数:
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *arg);
typedef void (*bufferevent_event_cb)(struct bufferevent* bev, short events, void* arg);
void bufferevent_setcb(
struct bufferevent* bufev,
bufferevent_data_cb readcb,
bufferevebr_data_cb writecb,
bufferevent_data_cb eventcb,
void* arg);
void bufferevent_getcb(
struct bufferevent* bufev,
bufferevent_data_cb* readcb,
bufferevebr_data_cb* writecb,
bufferevent_data_cb* eventcb,
void** arg);
5、操作bufferevent中的数据
1)获取evbuffer
struct evbuffer* bufferevent_get_input(
struct bufferevent* bev
);
struct evbuffer* bufferevent_get_output(
struct bufferevent* bev
);
2)向缓冲区添加数据
int bufferevent_write(
struct bufferevent* bev,
const void* data,
size_t size
);
将内存中从data处开始的size个字节写道缓冲区的末尾中
int bufferevent_write_buffer(
struct bufferevent_buffer* bev,
struct evbuffer* buf
);
清空原有缓冲区的内容,把buf写到缓冲区中去。
3)从缓冲区移除数据
size_t bufferevent_read(
struct bufferevent* bev,
void* buff,
size_t size
);
int bufferevent_read_buffer(
struct bufferevent* bev,
struct evbuffer* buff
);
用法同上
清空bufferevent:
int bufferevent_flush(
struct bufferevent* bev,
short iotype,
enum bufferevent_flush_mode state
);
连接监听器evconnlistener
顾名思义,提供了TCP监听和连接的方法。
- 创建和释放
struct evconnlistener* evconnlistener_new(
struct event_base* base,
evconnlistener_cb cb,
void* ptr,
unsigned flag,
int backlog,
ebutil_socket_t fd);
struct evconnlistener* evconnlistener_new_bind(
struct event_base* base,
evconnlistener_cb cb,
void* ptr,
unsigned flag,
int backlog,
const struct sockaddr* sa;
int socklen);
两个函数都分配和返回了一个新的连接监听对象。使用event_base来得知什么时候再给定的套接字上由新的TCP连接,新的连接到达的时候,调用回调函数。
flags:
LEV_OPT_LEAVE_SOCKETS_BLOCKING 设置新建连接套接字为阻塞
LEV_OPT_CLOSE_ON_FREE 关闭底层套接口
LEV_OPT_CLOSE_ON_EXEC 为套接字设置close_on_exec
其中cb是接收到新连接的时候的回调函数
参考代码。git@github.com:Icc-o/LibeventLearn.git clienttwo和servertwo