第十章 Bufferents

来源:互联网 发布:unity3d游戏案例 编辑:程序博客网 时间:2024/05/30 13:41

第十章 Bufferents

大部分时候,应用程序除了响应事件外,还要从连接中读数据到缓冲区或将缓冲区的数据写入连接中。一般写数据过程如下:
- 将要写的数据放入缓冲区
- 等待连接可写
- 尽可能的多写数据
- 标记已写的数据。如果还有更多的数据需要写,那么再次等待连接可写。

上面是缓冲IO方式。libevent可以很好的实现。

一个bufferevent由一个底层的transport(比如socket),一个read buffer和一个write buffer。与普通的事件不同的是,当一个底层的transport准备好读或写时,bufferevent调用对应的回调函数执行读写。当读写完成足够的数据时,将会调用用户指定的回调函数。

libevent定义了多种bufferevent。
- socket-based bufferevents: 从流式socket发送和接收数据。使用event_*接口实现的。
- asynchronous-IO bufferevents:使用windows下的IOCP接收和发送数据
- filtering bufferevents:处理底层的bufferevent中的输入和输出数据,如压缩或转换。
- paired bufferevents:两个bufferevents,相互传输数据

注:bufferevent仅用于流式socket,如TCP。将来可能会支持数据报协议,如UDP。

10.1 bufferevents and evbuffers

每个bufferevent都有两个相关的回调函数:读回调和写回调。默认情况下,只要从底层的transport读到数据,读回调函数将会被调用;只要写入底层的输出buffer有足够的空间,写回调函数将会被调用。你可以通过调整bufferevent的“watermarks”来改变这些函数的行为。

每个bufferevent有四种watermarks:
- Read low-water mark
只要read buffer中的数据达到low-water或更高时,bufferevents的读回调将被调用。默认是0,因此,只要read buffer中有数据可读,则回调函数就会被调用。
- Read high-water mark
如果bufferevents中的read buffer中的数据达到此水平时,bufferevents将会停止从从底层的transport读数据,直到read buffer中有足够的空间容纳数据。默认情况下是无限的,因此bufferevent不会停止从底层的transport读数据。
- Write low-water mark
如果output buffer中的数据达到或低于此水平时,bufferevents将会调用写回调函数。默认是0,因此除非output buffer为空时,才会调用写回调函数。
- Write high-water mark

bufferevent也有error回调和event回调。如当连接关闭时,错误出现时。定义了如下事件flags:
- BEV_EVENT_READING:在bufferevent读操作期间出现一个事件。
- BEV_EVENT_WRITING:在bufferevent写操作期间出现一个事件。
- BEV_EVENT_ERROR:在一个bufferevent操作期间出现一个错误。更多关于什么错误的信息,调用EVUTIL_SOCKET_ERROR()。
- BEV_EVENT_TIMEOUT:bufferevent上的定时时间到。
- BEV_EVENT_EOF:在bufferevent得到文件尾。
- BEV_EVENT_CONNECTED:在bufferevent上连接请求完成。

10.3 Deferred callbacks

默认情况下,当条件发生时,bufferevent对应的回调函数将会立马调用。当依赖关系复杂时,直接调用可以会带来麻烦。例如,当evbuffer A为空时,一个回调函数就将数据移入evbuffer;而当evbufer A满时,另一个回调函数会将数据从evbuffer中移出进行处理。由于这些调用发生在栈上,(如果依赖性增长不好?),可能会发生栈溢出。

为了解决这个问题,你可以让bufferevent延迟回调函数执行。当延迟回调的条件满足时,而不是立刻。

10.4 bufferevent的选项标签( option flags for bufferevents)

在创建bufferevent时,可以使用一个或多个flags改变bufferevent的行为。flags有:
- BEV_OPT_CLOSE_ON_FREE
当bufferevent被销毁时(free),关闭底层的transport。
- BEV_OPT_THREADSAFE
为bufferevent自动分配锁,使得它在多线程中是安全的。
- BEV_OPT_DEFER_CALLBACKS
该flag被设置时,bufferevent延迟所有的回调。
- BEV_OPT_UNLOCK_CALLBACKS
默认情况下,当bufferevent被设为线程安全时,在任何用户提供的回调函数被调用时,bufferevent的锁都是被持有的。设置该flag,在bufferevent调用回调函数时,它的锁会被释放。

10.5 Working with socket-based bufferevents

最简单的bufferevent是与socket一起工作。基于socket的bufferevent使用libevent的事件机制来探测底层网络socket是否准备好读和写,使用底层的网络调用(如readv,writev,WSASend,WSARecv)来完成传输和接收数据。

10.5.1 创建基于socket的bufferevent

struct bufferevent *bufferevent_socket_new(
0 0
原创粉丝点击