ACE反应器(Reactor)模式(2)
本贴转自http://www.cnblogs.com/TianFang/category/78013.html 作者:天方 在Socket编程中,常见的事件就是"读就绪","写就绪",通过对这两个事件的捕获分发,可以实现Socket中的异步操作。 Socket编程中的事件处理器 在前面我们已经介绍过,在ACE反应器框架中,任何都必须派生自ACE_Event_Handler类,并通过重载其相应会调事件处理函数来实现相应的回调处理的。在Socket编程中,我们通常需要重载的函数有
此外,为了使Reactor能通过I/O句柄找到对应的事件处理器,还必须重载其get_handle()方法以使得Reactor建立起I/O句柄和事件处理器的关联。 使用Reactor框架。 下面我们将以一个客户端的程序为例,介绍如何在Socket编程中使用Reactor框架。 一.建立一个客户端对象(事件处理器)。 客户端对象就是一个事件处理器,其声明如下: class Client:public ACE_Event_Handler 在Client 端中我只关心"读就绪"事件,故只重载了handle_input 函数(大多数应用下只需要重载handle_input 函数)。另外,在客户端还保存了一个ACE_SOCK_Stream 的peer 对象用来进行 Socket通信,同时封装了一个Peer() 函数返回它的引用。 二.重载相应回调处理函数 ACE_SOCK_Stream& Client::Peer() 几个函数的功能都非常简单,这里就不多做介绍了。 三.在Reactor中注册事件 首先让我们来看看相应的main函数的代码: int main(int argc,char *argv[]) 在这里可以看到,使用Reactor框架后,依然首先通过ACE_SOCK_Connector的connect函数来建立连接。建立连接后,可以通过ACE_Reactor::instance()->register_handler 函数来实现 Reactor的注册,实现I/O事件和Client对象的handle_input 方法相关联,它的第一个参数是事件处理器的地址,第二个参数是事件类型,由于这里只关心读就绪事件,故注册的事件类型是ACE_Event_Handler::READ_MASK 。 四.启动Reactor事件循环 通过如上设置后,我们就可以通过ACE_Reactor::instance()->handle_events() 启动 Reactor循环了,这样,每当服务器端有数据发送给客户端时,当客户端的数据就绪时,就回触发Client对象的handle_input 函数,将接收的数据打印出来。 通常的做法是,将Reactor事件循环作为一个单独的线程来处理,这样就不会阻塞main函数。 五.注销Reactor事件 Reactor事件的注销一般有两种方式,显式和隐式,下面将分别给予介绍。
在这个示例程序里,连接方只有一个Socket连接,Reactor的优势并没有体现出来,但在一些网络管理系统里,连接方需 要对多个需要管理的设备(服务器端)进行连接,在这种情况下使用Reactor模式,只需要多开一个Reactor事件循环线程就能实现事件多路分发复 用,并且不会阻塞,通过面向对象的回调方式管理,使用起来非常方便。 Reactor框架的另外一个常用的地方就是服务器端,一般是一个服务器端对应多个客户端,这样用Reactor模式能大幅提高并发能力,这方面的编程方法将在下一章给与介绍。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |