ACE Proactor架構

來源:互聯網
上載者:User

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

 

未完待續……

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.