ACE Proactor框架

本文介绍了ACEProactor框架的工作原理及使用方式,通过一个EchoServer示例程序详细讲解了如何利用该框架实现异步I/O操作,包括客户端连接处理、读写操作等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ACE Proactor简介
 前摄式I/O模型可以在多个I/O句柄上并行地发起一个货多个异步I/O操作,而无需等待它们完成。在每个操作完成时,OS会通知应用定义的完成处理器,由它随后对已完成的I/O操作的结果进行处理。
 
 相关框架类

/

 

先让我们看一个最简单的使用ACE Proactor框架的Echo Server程序:

 

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. #ifdef _DEBUG
  5. #pragma comment(lib,"ACED.lib")
  6. #else
  7. #pragma comment(lib,"ACE.lib")
  8. #endif
  9. #include "ace/OS_main.h"
  10. #include "ace/OS_NS_sys_socket.h"
  11. #include "ace/ACE.h"
  12. #include "ace/Service_Object.h"
  13. #include "ace/Asynch_IO.h"
  14. #include "ace/Proactor.h"
  15. #include "ace/message_block.h"
  16. #include "ace/Asynch_Acceptor.h"
  17. #include "ace/INET_Addr.h"
  18. /*************************************************************
  19. * 服务处理器
  20. * 实现接受客户端连接,并打印出客户端发送的消息
  21. * 有新的客户端连接进来的时候,框架会调用ACE_Asynch_Acceptor::make_handle
  22. * 方法,new一个Echo_Service的对象,一个连接对应一个Echo_Service的实例
  23. **************************************************************/
  24. class Echo_Service : public ACE_Service_Handler
  25. {
  26. public:
  27.     /*************************************************************
  28.     * 客户端连接断开(在handle_read_stream中判断是否失败或接受到长度为0
  29.     * 的消息)关闭
  30.     **************************************************************/
  31.     ~Echo_Service ()
  32.     {
  33.         if (this->handle () != ACE_INVALID_HANDLE)
  34.             ACE_OS::closesocket (this->handle ());
  35.     }
  36.     
  37.     /*************************************************************
  38.     * 有新的客户端连接进来
  39.     * 之前会调用ACE_Asynch_Acceptor::make_handle方法new一个此对象实例
  40.     **************************************************************/
  41.     virtual void open (ACE_HANDLE h, ACE_Message_Block&)
  42.     {
  43.         this->handle (h);
  44.         /*************************************************************
  45.         * 初始化异步读写
  46.         **************************************************************/
  47.         if (this->reader_.open (*this) != 0 || this->writer_.open (*this) != 0   )
  48.         {
  49.             ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p/n"),ACE_TEXT ("Echo_Service open")));
  50.             delete this;
  51.             return;
  52.         }
  53.         
  54.         /*************************************************************
  55.         * 发起一个异步读操作
  56.         **************************************************************/
  57.         ACE_Message_Block *mb;
  58.         ACE_NEW_NORETURN (mb, ACE_Message_Block (1024));
  59.         if (this->reader_.read (*mb, mb->space ()) != 0)
  60.         {
  61.             ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p/n"),ACE_TEXT ("Echo_Service begin read")));
  62.             mb->release ();
  63.             delete this;
  64.             return;
  65.         }
  66.     }
  67.     
  68.     /*************************************************************
  69.     * 读操作完成之后回调此函数
  70.     **************************************************************/
  71.     virtual void handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)
  72.     {
  73.         result.message_block ().rd_ptr ()[result.bytes_transferred ()] = '/0';
  74.         ACE_Message_Block &mb = result.message_block ();
  75.         if (!result.success () || result.bytes_transferred () == 0)
  76.         {
  77.             mb.release ();
  78.             delete this;
  79.         }
  80.         else
  81.         {
  82.             ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "%s" ), mb.rd_ptr() ) );
  83.             /*************************************************************
  84.             * 这里的write是向客户端发送消息(把收到的内容重新发给客户端)
  85.             **************************************************************/
  86.             if (this->writer_.write (mb, mb.length ()) == -1)
  87.             {
  88.                 ACE_ERROR ((LM_ERROR,
  89.                     ACE_TEXT ("%p/n"),
  90.                     ACE_TEXT ("starting write")));
  91.                 mb.release ();
  92.             }
  93.             else
  94.             {
  95.                 ACE_Message_Block *new_mb;
  96.                 ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024));
  97.                 this->reader_.read (*new_mb, new_mb->space ());
  98.             }
  99.         }
  100.         return;
  101.     }
  102.     
  103.     /*************************************************************
  104.     * 写操作完成之后回调此函数
  105.     **************************************************************/
  106.     virtual void handle_write_stream
  107.         (const ACE_Asynch_Write_Stream::Result &result)
  108.     {
  109.         ACE_Message_Block &mb = result.message_block ();
  110.         mb.release ();
  111.         return;
  112.     }
  113.     
  114. private:
  115.     ACE_Asynch_Read_Stream  reader_;        // 异步读工厂类
  116.     ACE_Asynch_Write_Stream writer_;        // 异步写工厂类
  117. };
  118. typedef ACE_Asynch_Acceptor<Echo_Service> MyAcceptor;   // 关于ACE_Asynch_Acceptor在下面介绍
  119. int main(int argc, char *argv[])
  120. {
  121.     ACE_INET_Addr addr(1500);
  122.     MyAcceptor server;
  123.     
  124.     if(server.open(addr)==-1)
  125.     {
  126.         ACE_DEBUG ((LM_DEBUG,
  127.             ACE_TEXT ("(%P|%t) %p/n"),
  128.             ACE_TEXT ("bind failed")));
  129.         return 1;
  130.     }
  131.     
  132.     while(1){
  133.         ACE_Proactor::instance ()->proactor_run_event_loop ();
  134.     }
  135.     
  136.     return 0;
  137. }

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()方法。

 

未完待续……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值