另一种较高效的做法是:服务器端保存一个Socket连接列表,然后对这个列表进行轮询,如果发现某个Socket端口上有数据可读时(读就绪),则调用该Socket连接的相应读操作;如果发现某个Socket端口上有数据可写时(写就绪),则调用该Socket连接的相应写操作;如果某个端口的Socket连接已经中断,则调用相应的析构方法关闭该端口。这样能充分利用服务器资源,效率得到了很大提高。
在Socket编程中就可以通过Select等相关API实现这一方式。但直接用这些API控制起来比较麻烦,并且也难以控制和移植,在ACE中可以通过Reactor模式简化这一开发过程。
反应器本质上提供一组更高级的编程抽象,简化了事件驱动的分布式应用的设计和实现。除此之外,反应器还将若干不同种类的事件的多路分离集成到易于使用的API中。特别,反应器对基于定时器的事件、信号事件、基于I/O端口监控的事件和用户定义的通知进行统一地处理。
ACE中的反应器与若干内部和外部组件协同工作。其基本概念是反应器框架检测事件的发生(通过在OS事件多路分离接口上进行侦听),并发出对预登记事件处理器(event handler)对象中的方法的“回调”(callback)。该方法由应用开发者实现,其中含有应用处理此事件的特定代码。
反应器模式在ACE中被实现为ACE_Reactor类,它提供反应器框架的功能接口。
使用ACE的反应器,只需如下几步:
(1)创建事件处理器ACE_Event_Handler的子类,并在其中实现适当的“handle_”方法,以处理想要的事件类型。
ACE_HANDLE get_handle() const ; // Reactor回调此函数以获得注册事件的处理句柄
virtual int handle_output(ACE_HANDLE handle); //socket写事件
virtual int handle_input(ACE_HANDLE handle); //socket读事件
virtual int handle_timeout(ACE_HANDLE handle); //socket超时事件
virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask mask) ;//socket 关闭事件
(2)在反应器上登记,同时传递其想要用以处理此事件的事件处理器的指针给反应器。
RSS_Accept_Handler rah(rss_addr,&qmm_data);
ACE_Reactor::instance()->register_handler(&rah,ACE_Event_Handler::ACCEPT_MASK); 通过调用反应器对象的register_handler(),将事件处理器登记到反应器。
|