略微加速

略速 - 互联网笔记

libevent笔记-bufferevent带buffer的事件

2020-05-08 leiting (4719阅读)

标签 C/C++ Linux

//libevent笔记-bufferevent带buffer的事件  
//转载请注明出处: yuliying的csdn博客.  
  
//封装了libevent的一些底层功能,如果不使用bufferevent,当网络读写事件发生时,用户需要自己将  
//数据写入read buffer,并自己发送write buffer的数据到网络. bufferevent 代替用户做了这些事情,   
//用户只需要一心处理read buffer收到的数据,并将要发送的数据写入write buffer , 框架会自动帮我们  
//收发这些数据.  
  
//bufferevent目前只支持TCP协议, UDP目前还不支持.  
//每个bufferevent结构体都带有两个evbuffer结构体,分别表示一个socket连接的读buffer和写buffer.  
//当你要发数据到客户端时,将数据添加到写buffer,读取客户端的数据时从读buffer里拿数据处理.  
  
//每个bufferevent有四个水位,水位的设置决定了读写回调函数被调用的时机和网络数据的读写:  
//1.读低水位(Read low-water mark):  
//  每当从网络读到数据之后,读buffer的容量大于或等于这个数值的时候,读回调函数被调用.  
//  默认为0,所以每次读到数据读回调函数都会被调用.  
//2.读高水位(Read high-water mark):  
//  如果读buffer的数据量达到这个水位,则会停止从网络读取数据,直到数据被我们处理.  
//3.写低水位:  
//  当写数据到网路之后,写buffer的数据量低于这个值,写回调函数被调用.  
//  默认为零,则在写buffer的数据被完全写到网络之后为空的时候调用写回调函数.  
//4.写高水位:  
//  暂时没有直接用处.  
  
//每个bufferevent有两个数据相关的回调函数,读回调和写回调.  
//读回调函数在每次从网络读到数据并且数据量>=读低水位的时候被调用.  
//写回调函数在足够多的数据被发送到网络后数据量<=读低水位调用.  
  
//bufferevent不仅有读写相关的回调函数,还有事件的回调函数.例如连接关闭或者连接发生错误.  
//支持以下事件类型:  
//1.BEV_EVENT_READING : 读事件.  
//2.BEV_EVENT_WRITING : 写事件.  
//3.BEV_EVENT_ERROR : 错误事件.关于错误的更多信息,请调用EVUTIL_SOCKET_ERROR()  
//4.BEV_EVENT_TIMEOUT : 超时事件.  
//5.BEV_EVENT_EOF : 连接关闭事件.  
//6.BEV_EVENT_CONNECTED : 连接成功事件.用在异步connect的时候.  
  
//回调函数的延迟回调  
//默认情况下,bufferevent的回调在相应的条件发生时立即被执行.(evbuffer的回调也是这样的)  
//在依赖关系复杂的情况下,这种立即调用会制造麻烦.比如说,假如某个回调在evbuffer A空的时候向其中  
//移入数据,而另一个回调在evbuffer A满的时候从中取出数据.这些调用都是在栈上发生的,  
//在依赖关系足够复杂的时候,有栈溢出的风险.要解决此问题,可以请求bufferevent(或者evbuffer)延迟其回调.  
//条件满足时,延迟回调不会立即调用,而是在event_loop()调用中被排队,然后在普通的事件回调之后执行.  
  
//当创建bufferevent时可以指定一些参数,改变bufferevent的行为  
//1.BEV_OPT_CLOSE_ON_FREE : 释放bufferevent时关闭底层传输端口。这将关闭底层套接字,释放底层bufferevent等  
//2.BEV_OPT_THREADSAFE : 加锁.  
//3.BEV_OPT_DEFER_CALLBACKS : 延迟回调所有回调函数.  
  
//创建一个基于socket套接字的bufferevent.如果想稍后再设置fd,可以先将fd设置为-1.  
//必须保证fd是非阻塞的,可以用 evutil_make_socket_nonblocking()函数来设置.  
//struct bufferevent *bufferevent_socket_new(struct event_base *base,evutil_socket_t fd , enum bufferevent_options options);  
  
//连接到一个地址,将套接字设置为非阻塞,并且创建bufferevent.  
//连接成功后会在回调函数进行通知(成功是BEV_EVENT_CONNECTED事件,失败是BEV_EVENT_ERROR事件).  
//连接成功前可以向写buffer写数据.  
//int bufferevent_socket_connect(struct bufferevent *bev,struct sockaddr *address, int addrlen);  
  
//为bufferevent设置回调函数.  
//void bufferevent_setcb(struct bufferevent *bufev,  
//    bufferevent_data_cb readcb, bufferevent_data_cb writecb,  
//    bufferevent_event_cb eventcb, void *cbarg);  
  
//其中数据回调函数的原型是  
//typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);  
  
//事件回调函数的原型是  
//typedef void (*bufferevent_event_cb)(struct bufferevent *bev,short events, void *ctx);  
  
//获取/设置/取消bufferevent关注的事件  
//short bufferevent_get_enabled(struct bufferevent *bufev);  
//void bufferevent_enable(struct bufferevent *bufev, short events);  
//void bufferevent_disable(struct bufferevent *bufev, short events);  
//可以设置的事件有 EV_READ 和 EV_WRITE , 如果不关注事件,bufferevent将不会读写数据.  
//bufferevent默认关注EV_WRITE , 但没有关注EV_READ , 不会从网络读数据.  
  
//设置bufferevent水位,参数events为EV_READ 或 EV_WRITE.  
//高水位设置为0表示无限制.  
//void bufferevent_setwatermark(struct bufferevent *bufev, short events,size_t lowmark, size_t highmark);  
  
//获取读buffer和写buffer  
//struct evbuffer *bufferevent_get_input(struct bufferevent *bufev);  
//struct evbuffer *bufferevent_get_output(struct bufferevent *bufev);  
  
//写数据到写buffer  
//int bufferevent_write(struct bufferevent *bufev,const void *data, size_t size);  
  
//将整个buffer追加到写buffer.  
//int bufferevent_write_buffer(struct bufferevent *bufev,struct evbuffer *buf);  
  
//从读buffer读取数据,并将该部分数据从读buffer移除.  
//size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size);  
  
//将数据从读buffer移除,并添加到我们提供的buffer里面  
//int bufferevent_read_buffer(struct bufferevent *bufev,struct evbuffer *buf);  
  
//获取/设置bufferevent的优先级,优先级参考之前笔记的event_base 和 event的优先级设置.  
//int bufferevent_priority_set(struct bufferevent *bufev, int pri);  
//int bufferevent_get_priority(struct bufferevent *bufev);  
  
//获取/设置文件描述符  
//evutil_socket_t bufferevent_getfd(struct bufferevent *bufev);  
//int bufferevent_setfd(struct bufferevent *bufev, evutil_socket_t fd);  
  
//从bufferevent获取event_base  
//struct event_base *bufferevent_get_base(struct bufferevent *bev);  
  
//上锁/解锁.同时锁住相关的读写buffer只有在初始化bufferevent的时候设置了BEV_OPT_THREADSAFE 才有效.  
//锁是递归的  
//void bufferevent_lock(struct bufferevent *bufev);  
//void bufferevent_unlock(struct bufferevent *bufev);  
  
//示例在libevent-evconnlistener一篇笔记中.


北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3