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()方法。
未完待續……