ACE Proactor简介
前摄式I/O模型可以在多个I/O句柄上并行地发起一个货多个异步I/O操作,而无需等待它们完成。在每个操作完成时,OS会通知应用定义的完成处理器,由它随后对已完成的I/O操作的结果进行处理。
相关框架类
/
先让我们看一个最简单的使用ACE Proactor框架的Echo Server程序:
- #include <iostream>
- #include <string>
- using namespace std;
- #ifdef _DEBUG
- #pragma comment(lib,"ACED.lib")
- #else
- #pragma comment(lib,"ACE.lib")
- #endif
- #include "ace/OS_main.h"
- #include "ace/OS_NS_sys_socket.h"
- #include "ace/ACE.h"
- #include "ace/Service_Object.h"
- #include "ace/Asynch_IO.h"
- #include "ace/Proactor.h"
- #include "ace/message_block.h"
- #include "ace/Asynch_Acceptor.h"
- #include "ace/INET_Addr.h"
- /*************************************************************
- * 服务处理器
- * 实现接受客户端连接,并打印出客户端发送的消息
- * 有新的客户端连接进来的时候,框架会调用ACE_Asynch_Acceptor::make_handle
- * 方法,new一个Echo_Service的对象,一个连接对应一个Echo_Service的实例
- **************************************************************/
- class Echo_Service : public ACE_Service_Handler
- {
- public:
- /*************************************************************
- * 客户端连接断开(在handle_read_stream中判断是否失败或接受到长度为0
- * 的消息)关闭
- **************************************************************/
- ~Echo_Service ()
- {
- if (this->handle () != ACE_INVALID_HANDLE)
- ACE_OS::closesocket (this->handle ());
- }
- /*************************************************************
- * 有新的客户端连接进来
- * 之前会调用ACE_Asynch_Acceptor::make_handle方法new一个此对象实例
- **************************************************************/
- virtual void open (ACE_HANDLE h, ACE_Message_Block&)
- {
- this->handle (h);
- /*************************************************************
- * 初始化异步读写
- **************************************************************/
- if (this->reader_.open (*this) != 0 || this->writer_.open (*this) != 0 )
- {
- ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p/n"),ACE_TEXT ("Echo_Service open")));
- delete this;
- return;
- }
- /*************************************************************
- * 发起一个异步读操作
- **************************************************************/
- ACE_Message_Block *mb;
- ACE_NEW_NORETURN (mb, ACE_Message_Block (1024));
- if (this->reader_.read (*mb, mb->space ()) != 0)
- {
- ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p/n"),ACE_TEXT ("Echo_Service begin read")));
- mb->release ();
- delete this;
- return;
- }
- }
- /*************************************************************
- * 读操作完成之后回调此函数
- **************************************************************/
- virtual void handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)
- {
- result.message_block ().rd_ptr ()[result.bytes_transferred ()] = '/0';
- ACE_Message_Block &mb = result.message_block ();
- if (!result.success () || result.bytes_transferred () == 0)
- {
- mb.release ();
- delete this;
- }
- else
- {
- ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "%s" ), mb.rd_ptr() ) );
- /*************************************************************
- * 这里的write是向客户端发送消息(把收到的内容重新发给客户端)
- **************************************************************/
- if (this->writer_.write (mb, mb.length ()) == -1)
- {
- ACE_ERROR ((LM_ERROR,
- ACE_TEXT ("%p/n"),
- ACE_TEXT ("starting write")));
- mb.release ();
- }
- else
- {
- ACE_Message_Block *new_mb;
- ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024));
- this->reader_.read (*new_mb, new_mb->space ());
- }
- }
- return;
- }
- /*************************************************************
- * 写操作完成之后回调此函数
- **************************************************************/
- virtual void handle_write_stream
- (const ACE_Asynch_Write_Stream::Result &result)
- {
- ACE_Message_Block &mb = result.message_block ();
- mb.release ();
- return;
- }
- private:
- ACE_Asynch_Read_Stream reader_; // 异步读工厂类
- ACE_Asynch_Write_Stream writer_; // 异步写工厂类
- };
- typedef ACE_Asynch_Acceptor<Echo_Service> MyAcceptor; // 关于ACE_Asynch_Acceptor在下面介绍
- int main(int argc, char *argv[])
- {
- ACE_INET_Addr addr(1500);
- MyAcceptor server;
- if(server.open(addr)==-1)
- {
- ACE_DEBUG ((LM_DEBUG,
- ACE_TEXT ("(%P|%t) %p/n"),
- ACE_TEXT ("bind failed")));
- return 1;
- }
- while(1){
- ACE_Proactor::instance ()->proactor_run_event_loop ();
- }
- return 0;
- }
ACE_Asynch_Acceptor
ACE_Asynch_Acceptor是Acceptor-Connector模式中的接收器角色的另一种实现。这个类提供了以下能力:
它发起异步的被动连接建立
它充当工厂,为每个被接受的连接创建一个新的服务器处理器
它可以取消先前发起的异步accept()操作
它提供了一个挂钩方法来在新连接被建立时获取对端的地址
它提供了一个挂钩方法来在初始化新服务处理器之前确认对端。
ACE_Asynch_Acceptor的模板参数是工厂所生成的服务类,称为ACE_Service_Handler.这个类充当了来自 ACE_Asynch_Acceptor的连接完成的目标。
ACE_Asynch_Acceptor实现了ACE_Handler::handle_accept()方法来处理每个accept()的完成,如下所示:
收集代表每个新连接的端点的ACE_INET_Addr
如果传给open()的validate_new_connection参数为1,调用validate_connection()方法,将相连对端的地址作为参数传给它。如果validate_connection返回-1,连接被中止。
调用make_handler()挂钩方法来为每个新连接获取服务处理器。缺省显示使用了operator new来动态分配新的处理器
设置新处理器的ACE_Proactor指针。
如果传给open()的pass_address参数为1,用本地和对端的地址做参数,调用ACE_Service_Handler::address()方法
设置新连接的I/O句柄,并调用新的服务处理器的open()方法。
未完待续……