libevent网络库--bufferevent
1概念
1.1原理
- bufferevent有两个缓冲区:也是队列实现只能读一次 先进先出
- 读缓冲: 加入读缓冲有数据,会触发读缓冲对应的回调函数,在回调函数中不再使用read函数 只能使用bufferevent_read函数
- 写缓冲bufferevent_write()向写缓冲写数据,这个写缓冲一旦有数据,就自动刷新–发送给对端,
- 发送成功 write_cb()回被调用 —通知写数据完成。

2操作函数
- 头文件:#include
2.1创建
struct bufferevent * ev;
struct bufferevent * bufferevent_socket_new(struct event_base *base, evutil_socket_t fd, int options);
2.1.1参数
| No. | 参数 | 说明 |
|---|---|---|
| 1 | base | 创建反应器返回指针 |
| 2 | fd | 封装到bufferevent内的fd |
| 3 | options | BEV_OPT_CLOSE_ON_FREE关闭传输端口,关闭套接字,释放bufferevent |
2.1.2返回值
- 成功:返回创建的bufferevent事件对象
2.2释放
void bufferevent_free(struct bufferevent* bev);//bev:创建返回值
2.3给bufferevent事件对象设置读写回调回调函数
void bufferevent_setcb(struct bufferevent *bufev,//bufferevent_data_cb readcb, //bufferevent_data_cb writecb,//bufferevent_event_cb eventcb, void *cbarg)//
2.3.1参数
| No. | 参数 | 说明 |
|---|---|---|
| 1 | bufev | 创建bufferevent事件返回指针 |
| 2 | readcb | 设置bufferevent 读缓冲对应的回调,自己封装,在其内部读数据 |
| 3 | writecb | 设置bufferevent 写缓冲对应的回调,基本不用传NULL |
| 1 | eventcb | 可传NULL |
| 1 | cbarg | 上面3个回调函数的参数 |
2.3.2回调函数
2.3.2.1read_cb
- 函数原型
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx){//ctx就是cbarg----------bufferevent_read();
}
- 读数据:我们定义的读缓冲的回调函数内部要调用bufferevent_read(),其作用从bufferevent输入的缓冲区移除事件。
- 所以要看下这个函数原型:
- ev_size_t bufferevent_read(struct bufferevent *bufev, void *data, ev_size_t size);
- 所以要看下这个函数原型:
2.3.2.2write_cb
- 函数原型
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);{//ctx就是cbarg没有什么用
}
- 写数据 :bufferevent_write()原型:
- int bufferevent_write(struct bufferevent *bufev, const void *data, ev_size_t size)
2.3.2.3event_cb
- 函数原型
typedefvoid(*bufferevent_event_cb(struct bufferevent *bev, short what, void *ctx){};
- 事件回调
what就是事件类型,类型有:#define BEV_EVENT_READING 0x01 /**< error encountered while reading */#define BEV_EVENT_WRITING 0x02 /**< error encountered while writing */#define BEV_EVENT_EOF 0x10 /**< eof file reached */#define BEV_EVENT_ERROR 0x20/**< unrecoverable error encountered */ #define BEV_EVENT_TIMEOUT 0x40 /**< user-specified timeout reached */#define BEV_EVENT_CONNECTED 0x80 /**< connect operation finished. */(请求的
2.4禁用缓冲区和获取缓冲区的状态
- 禁用
void bufferevent_disable(struct bufferevent *bufev,.. short event)//EV_READ | EV_ERITE
- 启用
short bufferevent_get_enable(struct bufferevent *bufev)
2.5启用缓冲区
- 新建的bufferevent写缓冲区是enable的,而读缓冲区是disable的,所以读的时候需要启用读的缓冲区。
int bufferevent_enable(struct bufferevent *bufev,.. short event)//EV_READ | EV_ERITE
2.6释放bufferevent
void bufferevent_free(struct bufferevent *bufev);// 参数:bufferevent_socket_new的返回值
2.7连接
int bufferevent_socket_connect(struct bufferevent *bev,//bufferevent事件对象 里面封装了fdstruct sockaddr *address, //服务器地址int socklen);//服务器地址长度
2.8evconnlistener_new_bind()
- 函数原型:
struct evconnlistener *evconnlistener_new_bind(struct event_base *base,//event_baseevconnlistener_cb cb, //监听回调函数,服务端接受连接之后,用户要做的操作,一旦被回调,说明在其内部应该与客户端完成连接void *ptr, //回调函数参数unsigned flags, int backlog,//listen()的第二个参数 -1表示最大值const struct sockaddr *sa, //服务器自己的地址结构int socklen);//大小
2.8.1参数cb
- 函数原型
typedef void (*evconnlistener_cb)(struct evconn listener *listener,evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr);
- 回调函数调用的时间:当接收到新连接时(即当有客户端连接时)会调用回调函数;
- 回调参数
- listener:成功创建的监听器,即evconnlistener_new_bind返回值;
- sock: 新接收的套接字,即客户端的套接字
- addr和len;分别是客户端的地址结构和长度;
- ptr:外部ptr传进来的参数。
2.8.2参数flags
- LEV_OPT_CLOSE_ON_FREE:如果设置了这个选项,释放连接监听器会关闭底层套接字;
- LEV_OPT_REUSEABLE: 端口复用
2.8.3返回值
成功创佳的监听器
3bufferevent使用步骤
- 第一步:创建event_base
- 创建 bufferevent 事件
- 给bufferevent事件对象设置回调
- 缓冲区开启
- 缓冲区关闭:
- 释放bufferevent
4客户端和服务器
4.1对比
- 客户端
- 普通 :socket() connect();
- buffer:bufferevent_socket_connect
- 服务端
- socket() bind() listen() accept()
- evconnlistener_new_bind()这一个函数相当于socket() bind() listen() accept()的作用
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
