当前位置: 代码迷 >> 综合 >> libevent学习笔记——event,bufferevent
  详细解决方案

libevent学习笔记——event,bufferevent

热度:34   发布时间:2023-11-27 23:51:53.0

文章目录

  • libevent框架:
  • event事件
    • 创建事件event:
    • 添加事件到event_base
    • 从base上摘下事件
    • 销毁事件
  • 带缓冲区的事件bufferevent:用于socket通信
    • 创建,销毁bufferevent:
    • 给bufferevent设置回调
    • 启动和关闭bufferevent的缓冲区:
    • 客户端连接
    • 服务器创建监听器:
  • 服务器逻辑过程:
  • 客户端逻辑过程:

libevent框架:

特性:
基于"事件"异步通信模型。
1.创建event_base (乐高底座)
struct event_base * event_base_new(void);
struct event_base * base = event_base_new();
2.创建 事件event
常规事件 event ——> event_new();
bufferevent ——> bufferevent_new();
3.将事件添加到base上
int event_add(struct event *ev,const timeval *tv)
4.循环监听事件满足
int event_base_dispatch(struct event_base *base);
5.释放event_base
void event_base_free(base);

event事件

创建事件event:

	struct event *event_new(struct event_base *base,evutil_socket_t fd,short what,event_callback_fn cb, void* arg);base:event_base_new()返回值fd:绑定到event上的文件描述符what:为监听事件类型(读,写,异常)EV_READ		一次 读事件EV_WRITE	一次 写事件EV_PERSIST	持续触发。结合event_base_dispatch函数使用,生效。cb:回调函数typedef void(*event_callback_fn)(evutil_socket_t fd,short,void*)arg:回调函数参数返回值:成功创建的event

添加事件到event_base

	int event_add(struct event *ev,const struct timeval *tv)ev:event_new()函数返回的事件tv:NULL

从base上摘下事件

	int event_del(struct event *ev)ev:event_new()函数返回的事件

销毁事件

int event_free(struct event *ev)ev:event_new()函数返回的事件

带缓冲区的事件bufferevent:用于socket通信

头文件 #include<event/bufferevent.h>

创建,销毁bufferevent:

struct bufferevent *bufferevent_socket_new(struct event_base *base,evutil_socket_t fd,enum bufferevent_options options);base:event_base_new()返回值fd:封装到bufferevent内的文件描述符options:BEV_OPT_CLOSE_ON_FREE :释放 bufferevent 时关闭底层传输端口。这将关闭底层套接字,释放底层 bufferevent 等。BEV_OPT_THREADSAFE :自动为 bufferevent 分配锁,这样就可以安全地在多个线程中使用 bufferevent。BEV_OPT_DEFER_CALLBACKS :设置这个标志时, bufferevent 延迟所有回调,如上所述。BEV_OPT_UNLOCK_CALLBACKS :默认情况下,如果设置 bufferevent 为线程安全 的,则 bufferevent 会在调用用户提供的回调时进行锁定。设置这个选项会让 libevent 在执行回调的时候不进行锁定。返回:成功创建的bufferevent事件对象。int bufferevent_free(struct bufferevent *ev);

给bufferevent设置回调

对比event: event_new(fd,callback); event_add()——挂到event_base。
而bufferevent:

void bufferevent_setcb(struct bufferevent *bufev,bufferevent_data_cb readcb, bufferevent_data_cb writecb,bufferevent_event_cb eventcb, void *cbarg);bufev :bufferevent_socket_new()返回值readcb:设置bufferevent 读缓存,对应回调函数 read_cb{buffevent_read()读数据}writecb:设置bufferevent 写缓存,对应回调函数 write_cb{}——给调用者,发送成功通知.可以为NULL,bufferevent_write()在这个回调之前eventcb:设置事件回调.可以获取读写状态与某些异常。可传NULLcbarg:回调函数参数://事件回调函数typedef void (*bufferevent_event_cb)(struct bufferevent *bev,short events, void *ctx);void event_cb(struct bufferevent*bev,short events,void ctx){//可以观测连接状态}	events:常用BEV_EVENT_CONNECTED  	//连接时触发事件回调//read回调函数类型:typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void*ctx);		void read_cb(struct bufferevent*bev,void* cbarg){...bufferevent_read();//真正的读操作实体}bufferevent_read()函数的原型:size_t buffevent_read(struct bufferevent *bev,void* buf,size_t bufsize);//write回调函数类型与read一致bufferevent_write()函数的原型:int buffevent_write(struct bufferevent *bev,const void* buf,size_t bufsize);write的回调在bufferevent_write调用之后产生,无太多实际意义

启动和关闭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);	

客户端连接

相当于socket() connect()

	int bufferevent_socket_connect(struct bufferevent *bev,struct sockaddr *address, int addrlen);bev:bufferevent事件对象(封装了fd)address 和 addrlen 参数跟标准调用 connect()的参数相同

服务器创建监听器:

相当于服务端的socket,bind,listen与accept
struct evconnlistener *evconnlistener_new_bind(struct event_base *base,evconnlistener_cb cb, void *ptr, unsigned flags, int backlog,const struct sockaddr *sa, int socklen);base:event_basecb:回调函数,一旦被回调,说明在其内部应该与客户端通信ptr:回调函数的参数flags:"可识别标志"LEV_OPT_CLOSE_ON_FREE:释放bufferevent是关闭底层传输端口。这将关闭底层套接字,释放底层buffereventLEV_OPT_REUSEABLE:端口复用back:listen的2参。传-1:表示使用默认最大值	sa:服务器自己地址结构体socklen:服务器自己的地址结构体大小返回值:成功创建的监听器。回调函数具体结构:typedef void (*evconnlistener_cb)(struct evconnlistener *listener,evutil_socket_t sock, struct sockaddr *addr, int len, void *ptr);listener:evconnlistener_new_bind函数的返回值sock:用于通信的文件描述符addr:客户端的IP+端口len:addr的lenptr:外部ptr传递进来值

服务器逻辑过程:

  1. 创建event_base
  2. 封装listner_cb在函数内部。完成与客户端的动心
  3. 创建监听服务器 evconnlistener_new_bind,设置回调函数,当客户端连接时,回调函数被调用
  4. 创建bufferevent事件对象,bufferevent_socket_new();
  5. 使用bufferevent_setcb()函数给bufferevent的read、write、event设置回调函数
  6. 当监听事件满足时,read_cb被调用,在其内部bufferevent_read()
  7. 设置读缓冲,写缓冲的使能状态
  8. 启动循环event_base_dispath();
  9. 释放连接,event_base
    ps:其中4,5,6,7步在listener_cb中完成

客户端逻辑过程:

  1. 创建event_base
  2. 使用bufferevent_socket_new()创建一个跟服务器通信的bufferevent事件对象
  3. 使用bufferevent_socket_connect()连接服务器
  4. 使用bufferevent_setcb()函数给bufferevent的read、write、event设置回调函数
  5. 设置读缓冲,写缓冲的使能状态
  6. 接收,发送数据bufferevent_read()/bufferevent_write()
  7. 启动循环event_base_dispath();
  8. 释放资源
  相关解决方案