




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、CJ000032RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19971/82ACEACE 開發指南開發指南( (初級初級) )CJ000032RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19972/82文檔信息文檔信息作者鄭明智創建日期2006-12-19版本1.0部門名稱開發部修訂文檔歷史記錄修訂文檔歷史記錄日期日期版本版本說明說明作者作者2006-12-191.0Reactor鄭明智2006-12-271.1增加 Proactor 的內容鄭明智2006-12-281.2增加 ACE Task 的內容鄭明
2、智CJ000032RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19973/82目錄目錄1.1.介紹介紹 .11.11.1目的目的.11.21.2文檔協定文檔協定.11.31.3閱讀者建議閱讀者建議.11.41.4術語說明術語說明.11.51.5翻譯約定翻譯約定.21.61.6相關資料相關資料.21.71.7參考文獻參考文獻.21.81.8補充說明補充說明.22.2.ACEACE 簡介及環境搭建簡介及環境搭建.32.1ACE 簡介簡介 .32.2本指南的主要內容本指南的主要內容.32.3獲取獲取 ACE.42.4編譯編譯 ACE.42.4.1為什么要編
3、譯 ACE .42.4.2在 Window 上編譯.42.4.3在 Linux 上編譯.52.5前行的路標前行的路標.63.3.ACEACE REACTORREACTOR 框架框架.63.1Reactor(反應器)框架(反應器)框架 .63.1.1ACE_Event_Handler(事件處理器) .73.1.2ACE_Reactor.93.2Acceptor(接受器接受器)-Connector(連接器連接器)框架框架.113.2.1ACE_Svc_Handler(服務處理器).123.2.2ACE_Acceptor.143.2.3ACE_Connector.153.3ACE Reactor S
4、erver (Demo).173.3.1需求 .173.3.2實現 .173.3.3ACE 工具類 .253.3.4Server 改進.26CJ000032RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19974/823.4ACE Reactor Client (Demo).293.4.1需求 .293.4.2實現 I.293.4.3使用超時機制發送消息 .333.4.4實現 II.333.5前行的路標前行的路標.374.4.ACEACE PROACTORPROACTOR 框架框架.384.1Proactor(前攝器)框架(前攝器)框架.384.1.1
5、異步 I/O 工廠類.394.1.2ACE_Handler(完成處理器).414.1.3ACE_Message_Block.424.1.4ACE_Proactor.434.2前攝式前攝式 Acceptor-Connector 框架框架.444.2.1ACE_Service_Handler .454.2.2ACE_Asynch_Acceptor .464.2.3ACE_Asynch_Connector .464.3既生既生 Proactor,何生,何生 Reactor (二者的應用范圍二者的應用范圍).464.4ACE Proactor Server (Demo) .474.4.1需求 .474
6、.4.2實現 .474.5前行的路標前行的路標.545.ACE TASK 框架框架.555.1我們的新需求我們的新需求.555.2Task(任務任務)框架框架.555.3ACE_Message_Queue.565.4ACE_Task.595.5Demo(Reactor Client 的改寫的改寫).615.5.1需求 .615.5.2實現 .615.6基本的線程安全性基本的線程安全性.715.6.1互斥體(Mutex).715.6.2守衛(Guard).755.7前行的路標前行的路標.766.總結總結 .777.常見問題常見問題.77CJ000032RAS-001開發指南 Made by Ex
7、pert Team上海超捷系統集成有限公司,19975/82CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19971/821.1. 介紹介紹1.11.1 目的目的 本指南作為使用 ACE 框架開發應用程序的參考,以期能夠對使用 ACE 框架的同事有所幫助。1.21.2 文檔協定文檔協定本文檔的書寫遵循公司定義的文檔規范。本指南寫作時,ACE 最新的穩定版本為 5.5 版。本指南中觀點和代碼并不保證適用于后續的 ACE 版本。本指南旨在幫助新手入門,如果您已對 ACE 有一定使用經驗并想更深入了解 ACE,建議您閱讀 ACE 的相關書籍。
8、1.31.3 閱讀者建議閱讀者建議本指南假定閱讀者有 C+的開發經驗和通信程序的開發經驗,文檔中 C+及 Socket 等開發知識及相關概念不再贅述。1.41.4 術語說明術語說明C/S Client/Server 客戶端/服務器架構Client 客戶端Server 服務器ACE 自適配通信環境 (Adaptive Communication Environment)Reactor 反應器,高效的事件多路分離和分派提供可擴展的面向對象框架Proactor 前攝器aio 異步 I/OAsynchronous I/O 異步 I/OEpoll Linux 從 2.6 開始支持的異步事件 I/O 技術
9、CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19972/821.51.5 翻譯約定翻譯約定Method/Function 方法Nested Class 內部類Callback 回調Hook Method 掛鉤方法Handle 句柄Template 模板Daemon 守護Override/ Overwrite 覆蓋Overload 重載1.61.6 相關資料相關資料ACE-5.5.zipMagic C+ 參考文獻參考文獻1 ACE 程序員指南 網絡與系統編程的實用設計模式2 C+網絡編程(卷 1) 運用 ACE 和模
10、式消除復雜性3 C+網絡編程(卷 2) 基于 ACE 和框架的系統化復用4 ACE 自適配通信環境中文技術文檔 中篇 ACE 程序員教程5 ACE API 列表6 ACE 源代碼1.81.8 補充說明補充說明1 本文檔中提到的資料,工具,代碼都放在了 相關資料放在0upload開發部技術組ACE 目錄下。2 如果您發現本指南有錯誤或者疏漏,請通知作者修改,以使本指南能夠更好的幫助大家。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19973/822.2. ACEACE 簡介及環境搭建簡介及環境搭建2.1 ACE 簡
11、介簡介ACE 自適配通信環境 (Adaptive Communication Environment)是面向對象的框架和工具包,它為通信軟件實現了核心的并發和分布式模式。ACE 包含的多種組件可以幫助通信軟件的開發獲得更好的靈活性、效率、可靠性和可移植性。ACE 中的組件可用于以下幾種目的:并發和同步 進程間通信(IPC) 內存管理 定時器 信號 文件系統管理 線程管理 事件多路分離和處理器分派 連接建立和服務初始化 軟件的靜態和動態配置、重配置 分層協議構建和流式框架 分布式通信服務:名字、日志、時間同步、事件路由和網絡鎖定,等等。 上面是比較官方的介紹。總之,如果你想用 C+實現一個通信程
12、序,而你又不想糾纏于Windows/Linux 等各平臺不同的 Socket 細節,那就可以考慮 ACE 框架。ACE 經過 10 余年的開發,已經不僅僅是通信的包,還實現了很多其它功能比如內存管理,文件系統管理等,可以滿足您大多數開發的需要。而且 ACE 是被全世界很多項目采用的可以稱的上是電信級別的框架。ACE 是跨平臺的,完全可以在 Windows 上開發,運行在 Linux 上(當然,與 Java 不完全相同的是您需要重新編譯鏈接。而且如果您的程序使用了 GUI 的包,這么做是行不通的)。ACE 的簡介就到這里。當我們使用 ACE 開發了一些程序,對 ACE 有了一定的認識之后,再回過
13、頭來進一步認識 ACE。2.2 本指南的主要內容本指南的主要內容本指南的目標是 ACE 零基礎 到 可以用 ACE 開發一些簡單的 C/S 程序。因此本指南的主要內容有:CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19974/821ACE 的獲取編譯首先介紹如何搭建 ACE 開發環境的問題。2ACE Reactor/Proactor 框架接下來本文并不打算像其它 ACE 的書籍從 ACE 歷史介紹,基礎機制講起,而是直接進入Reactor/Proactor 框架的介紹及使用這 2 個框架來開發程序,給初學者最想要的東西。3ACE 其他
14、機制最后對 ACE 的其他框架機制等做一概要介紹,比如 ACE_Task 機制,線程管理,同步機制等。2.3 獲取獲取 ACE從服務器上獲取 ACE-5.5.zip。或者從 /previous_versions/ 下載你需要的 ACE 版本。2.4 編譯編譯 ACE2.4.1 為什么要編譯為什么要編譯 ACE應用程序在鏈接及運行時需要使用 ACE 的庫和 dll 文件(Windows),而你下載的包里沒有這些文件或者不適合你的平臺。這時候就需要自己編譯 ACE。編譯一般來說需要花很長時間。注 1:項目組的其他人或者公司里的同事可
15、能已經有編譯好的庫文件,如果你不想花時間編譯 ACE,可以向其他人索取。服務器上有 ace5.3 版本在 gcc2.96/3.23 編譯通過的 rpm 文件,如果適合你的平臺,直接安裝即可。注 2:下面的在 Windows/Linux 編譯部分取自陳昕發的貼,本文做了適當修改。文中目錄等請注意修改成符合你的環境的目錄等。陳昕原貼在 8/bbs/viewthread.php?tid=1085&fpage=1 2.4.2 在在 Window 上編譯上編譯1.1. 解壓縮到本地目錄解壓縮到本地目錄例:解壓縮到C:ACE_wrappers2.2.查看安裝向導查
16、看安裝向導ACE 有自帶的安裝向導文件C:ACE_wrappersACE-INSTALL.html查看 ACE-INSTALL.html 文件中的 Building and Installing ACE on Windows with Microsoft Visual C+章節,按照上面所寫即可,下面是對此過程的總結CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19975/823.3.確定編譯環境確定編譯環境本文使用的是 C+.net framework 1.1,以下為該編譯環境下的步驟4.4.新建新建 config.hconfig.h
17、 文件文件由于 ACE 支持很多操作系統,因此必須建立一個 config.h 文件,在該文件包含相應的操作系統的頭文件,從而讓 ACE 知道將在什么操作系統下進行編譯進入C:ACE_wrappersace目錄,新建 config.h 文件,在 config.h 文件中添加#include ace/config-win32.h如果系統為 Windows98/Me,那么需要添加#define ACE_HAS_WINNT4 0如果需要使用標準 C+的類庫(例 iostream 等),那么需要添加#define ACE_HAS_STANDARD_CPP_LIBRARY 1如果需要使用 MFC(不推薦)
18、,那么需要添加#define ACE_HAS_MFC 15.5.設置環境變量設置環境變量開始-運行-cmdset ACE_ROOT=C:ACE_wrappers6.6.使用使用 環境編譯環境編譯打開 ACE.sln,可進行 debug/release 編譯7.7.生成生成.lib.dll.lib.dll 文件文件生成的 lib 和 dll 文件在 C:ACE_wrapperslib。2.4.3 在在 Linux 上編譯上編譯注:該步驟使用 ACE-5.4.7 測試成功1.1.解壓縮到本地目錄解壓縮到本地目錄例:#pwd/home/xchen#tar -xzvf ACE.tar.gz2.2.設置
19、環境變量設置環境變量#su #vi /etc/profile在 export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRC 下加入以下兩行export ACE_ROOT=/usr/local/ACE_wrappersexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ACE_ROOT/ace#. /etc/profileCJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19976/823.3.建立編譯環境建立編譯環境#cd /home/xchen/ACE_wr
20、appers#mkdir build#cd build#./configure4.4.配置配置 config.hconfig.h 文件文件./configure 之后,系統會在/home/xchen/ACE_wrappers/build 下建立 ace/conig.h 文件在/ ACE configuration header file 下行添加#include ace/config-linux.h5.5.編譯編譯#cd /home/xchen/ACE_wrappers/build#make6.6.生成生成.so.so 文件文件生成的 so 文件在/home/xchen/ACE_wrapper
21、s/build/ace/.libs 目錄下。2.5 前行的路標前行的路標對 ACE 感興趣,可以訪問 ACE 網站: /%7Eschmidt/ACE.htmlACE 的 Yahoo Group: http:/ 開發者論壇(中文):http:/ 3.3. ACEACE ReactorReactor 框架框架3.1 Reactor(反應器)框架(反應器)框架在編寫通訊程序時,如果服務器需要處理多個客戶端的連接,傳統做法是為每個客戶端創建一個進程或者線程。在大多數情況下,這種方法是可以解決問題的。但是,在某些情況下,進程線程創建維護并發的開銷是無法讓人接受
22、的。而 ACE Reactor 框架通過事件多路分離器,只需要用一個進程或者線程就可以處理多個客戶端的連接的事件。而且用戶程序使用 Reactor 框架也非常的簡單,只需要做 3 件事情:1)從 ACE_Event_Handler 派生子類,并 Overwrite 特定的事件虛回調方法。(比如 handle_input, handle_timeout)。2)向 ACE_Reactor 類登記你剛才創建的 ACE_Event_Handler 子類。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19977/823)運行 ACE_Reacto
23、r 事件循環。Reactor 的含義被動反應,可以讓我們理解它的精髓:它是事件驅動的,就像 Windows 的事件驅動一樣。下面是 ACE Reactor 框架的類圖和描述。ACE 類類描述描述ACE_Time_Value提供時間和持續時間(Duration)的可移植,規范化的表示ACE_Event_Handler抽象類,其定義的掛鉤(hook)方法是 ACE_Reactor 回調的目標。大多數通過 ACE 開發的應用事件處理器都是ACE_Event_Handler的后代。ACE_Timer_Queue抽象類,定義定時器隊列的能力和接口。ACE 含有多種派生自ACE_Timer_Queue 的
24、類,為不同的定時機制提供了靈活的支持。ACE_Reactor提供了一個接口,用來在 ACE 框架中管理事件處理器登記,并執行事件循環來驅動事件檢測,多路分離和分派。我們這里只關心 ACE_Event_Handler 和 ACE_Reactor 類。3.1.1 ACE_Event_Handler(事件處理器事件處理器)ACE_Event_Handler 是 ACE 中所有反應式事件處理器的基類。其接口如下所示:方法方法描述描述ACE_Event_Handler()指派與事件處理器相關聯的 ACE_Reactor 指針。ACE_Event_Handler()將其自身從反應器的通知機制中移出。han
25、dle_input()輸入事件(如 連接或數據事件)發生時的掛鉤(hook)方法。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19978/82handle_output()輸出事件成為可能時(如 流控制緩和或非阻塞式連接完成時)被調用的掛鉤方法。handle_exception()異常事件(如 TCP 緊急數據的到達)發生時被調用的掛鉤方法。handle_timeout()在定時器到期時被調用的掛鉤方法。handle_signal()OS 發出信號時(或是 POSIX 信號,或是 Windows 同步對象遷移到激發(Signaled)
26、狀態時)被調用的掛鉤方法。handle_close()在其他 handle_*() 掛鉤方法返回-1 或者當ACE_Reactor:remove_handler()被顯式調用來解除事件處理器的登記時,執行用戶定義的中止活動的掛鉤方法。get_handle()返回底層的 I/O 句柄。如果事件處理器只處理時間驅動的時間,該方法可實現為 no-op(空操作)reactor()訪問器,用于 獲取/設置可與ACE_Event_Handler 相關聯的ACE_Reactor 指針。priority()訪問器,用于 獲取/設置 事件處理器的優先級。在開發一個普通的 C/S 應用程序時,只需 Overwri
27、te handle_input() 和 handle_close() 這2 個回調方法也就足夠了。可以在 Reactor 的定時器隊列設置定時器(參考下面的 Reactor 接口),當超時事件發生時handle_timeout() 會來處理超時時應執行的操作。下面討論一下使用ACE_Event_Handler 時注意的 3 個方面:1 1事件類型:事件類型:在向 Reactor 登記事件處理器的時候,必須指定事件類型。事件類型定義在ACE_Event_Handler中,包括下面幾種:事件類型事件類型描述描述READ_MASK指定輸入事件(如數據出現在 socket 或文件句柄上)。反應器分派h
28、andle_input() 來處理輸入事件。WRITE_MASK指定輸出事件(如在流控制緩和時)。反應器分派handle_output()來處理輸出事件。EXCEPT_MASK指定異常事件(如緊急數據出現在 socket 上)。反應器分派 handle_exception()來處理異常事件。ACCEPT_MASK指定被動模式的連接事件。反應器分派 handle_input() 來處理連接事件。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,19979/82CONNECT_MASK指定非阻塞式連接的完成。反應器分派handle_output
29、() 來處理非阻塞式連接的完成事件。可以對這些事件進行組合(|)來高效的定義一組事件。這組事件被填充在 ACE_Reactor:register_handler() 方法的 ACE_Reactor_Mask 參數。2 2掛鉤方法的返回值掛鉤方法的返回值登記的事件發生時,反應器會分派相應的 handle_*() 來處理。而這些方法的返回值需注意:返回值返回值描述描述0指示反應器應繼續為此事件處理器檢測和分派所登記的事件。對于需要重復處理一個事件的事件處理器(比如當有數據可讀時從 Socket 讀取數據),這種行為是常見的。 0也指示反應器應繼續為此事件處理器檢測和分派所登記的事件。此外,如果在處
30、理了某個 I/O 事件后返回值大于0,反應器將在阻塞它的事件多路分離器之前,再次在句柄上分派此事件處理器。-1指示反應器停止為此事件處理器檢測已登記的事件。在反應器移除此事件處理器之前,它調用事件處理器的 handle_close()方法,傳給該方法正在被解除登記的事件的ACE_Reactor_Mask值。所以,我們在使用 Reactor 框架來開發 C/S 程序時,一般應在handle_*() 方法里返回 0。3 3清理事件處理器清理事件處理器handle_close()方法會在某個掛鉤方法決定要進行清理時被調用。handle_close()方法可隨即進行用戶定義的關閉活動,如釋放內存,關閉
31、 IPC 對象等。Reactor 框架會忽略handle_close()方法的返回值。如上所述,Reactor 只會在掛鉤方法返回負值,或事件處理器被顯式移除時調用handle_close(),而不會在 IPC 機制到達文件末尾或 I/O 句柄被本地或遠程關閉時調用handle_close()。因此,應用必須檢測 I/O 句柄何時關閉,并采取措施。比如,當 recv()或 read()調用返回 0 時,事件處理器應從handle_*() 方法里返回 -1,或調用 ACE_Reactor:remove_handler()。3.1.2 ACE_ReactorACE_Reactor是 Reactor
32、 模式的核心類,Reactor 模式的注冊事件處理器,運行事件循環等功能都要通過這個類來進行。ACE_Reactor 實現了 Faade 模式,為應用程序提供了各種訪問 Reactor 框架特性的接口。1 1初始化和析構方法:初始化和析構方法:方法方法描述描述CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199710/82ACE_Reactor() open()這兩個方法創建并初始化反應器的實例。ACE_Reactor() close()這兩個方法清理反應器在初始化時分配的資源。2 2事件處理器管理方法事件處理器管理方法方法方法描述描述
33、register_handler()為基于 I/O 和信號的事件登記事件處理器remove_handler()移除某事件處理器,使其不再參加基于 I/O 和信號的事件分派suspend_handler()暫時停止分派事件給某事件處理器resume_handler()恢復為先前掛起的事件處理器分配事件mask_ops()獲取,設置,增加或者清除與某事件處理器相關的事件類型及掩碼schedule_wakeup()將指定的掩碼增加到某事件管理器的條目中,該處理器在之前必須已通過 register_handler()登記過。cancel_wakeup()從某事件處理器的條目中清除指定的掩碼,但并不移除
34、該事件處理器3 3事件循環事件循環(Event-loop)(Event-loop)方法方法方法方法描述描述handle_events()等待事件發生,并隨即分派與之相關聯的事件處理器。可通過超時參數限制花費在等待事件上的時間。run_reactor_event_loop()反復調用 handle_events() 方法,直至其失敗,或者reactor_event_loop_done() 返回 1,或者超時(可選)。end_reactor_event_loop()指示反應器關閉其事件循環。reactor_event_loop_done()在反應器的事件循環被end_reactor_event_l
35、oop()調用結束時返回 14 4定時器管理方法定時器管理方法方法方法描述描述schedule_timer()登記一個事件處理器,它將在用戶規定的時間后被執行。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199711/82cancel_timer()取消一個或多個之前登記的定時器。我們可以使用這兩個方法來使代碼具有超時特性,當超時發生時,事件處理器的 handle_timeout()方法會被調用。5 5通知方法通知方法反應器擁有一種通知機制,應用可將其用于把事件和事件處理器插入反應器的分派引擎中。方法方法描述描述notify()將事件
36、(及可選的事件處理器)插入反應器的事件檢測器中,從而使其在反應器下次等待事件時被處理max_notify_iterations()設置反應器將在其通知機制中分派的處理器的最大數目。purge_pending_notifications()從反應器的通知機制中清除指定的事件處理器或所有事件處理器6 6實用方法實用方法(Utility(Utility Method)Method)方法方法描述描述instance()靜態方法,返回指向單體(Singleton) ACE_Reactor的指針。這是通過 Singleton 模式和 Double-Checked Locking Optimization
37、模式來創建和管理的。owner()使某個線程“擁有”反應器的事件循環。因為大部分的應用程序都需要實現 Server 或者 Client 端的內容,所以下面我們將分別實現一個Reactor 的 Server 和 Client。ACE 也提供了實現 Server 和 Client 的半成品,Acceptor 和 Connector 框架。3.2 Acceptor(接受器接受器)-Connector(連接器連接器)框架框架下面是Acceptor-Connector框架類的類圖。圖中我們可以看到ACE_Acceptor, ACE_Connector繼承自我們前面提到的ACE_Event_Handler
38、。然后ACE_Svc_Handler是繼承自ACE_Task的,而ACE_Task其實也是ACE_Event_Handler的后代。根據前面提到的 Reactor 開發 3 步驟,我們只需要將 ACE_Svc_Handler 登記到 Reactor 即可進行事件處理。對我們開發應用程序而言,我們只需要關心 ACE_Acceptor, ACE_Connector, ACE_Svc_Handler這 3 個類。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199712/82ACE 類類描述描述ACE_Svc_Handler表示某個已連接服務
39、的本地端,其中含有一個用于與相連對端通信的 IPC 端點。ACE_Acceptor該工廠被動的等待接受連接,并隨即初始化一個ACE_Svc_Handler 來響應來自對端的主動連接請求。ACE_Connector該工廠主動的連接到對端接受器,并隨即初始化一個 ACE_Svc_Handler 與其相連對端通信。通俗的說,ACE_Acceptor 就是我們要實現的 Server,ACE_Connector就是我們要實現的Client。當 Client 連接到 Server 時,會創建一個ACE_Svc_Handler 來處理事件(比如接收到數據,連接被斷開等);而 Server 端也會為每個 Cl
40、ient 創建一個ACE_Svc_Handler 來處理事件。3.2.1 ACE_Svc_Handler(服務處理器服務處理器)如上所述,ACE_Svc_Handler 就是用來處理事件,那么主要需要處理那些事件呢?1 1服務創建和激活方法服務創建和激活方法方法方法描述描述ACE_Svc_Handler()由接受器或連接器在創建服務處理器時調用的構造方法open()由接受器或連接器自動調用來初始化服務處理器的掛鉤方法。ACE_Svc_Handler已經在open方法里,把自己登記到Reactor事件循環,登記的事件類型為READ_MASK。所以我們的代碼將變得更加簡單。2 2服務處理方法服務處
41、理方法CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199713/82方法方法描述描述svc()ACE_Svc_Handler從ACE_Task 繼承來的 svc() 掛鉤方法。在服務處理器的activate() 方法被調用后,其大部分后續處理都可在 svc() 掛鉤方法中執行。handle_*() ACE_Svc_Handler 從ACE_Event_Handler繼承的 handle_*() 方法。因此,服務處理器可以向反應器登記自身,以在它感興趣的各種事件發生時接收像handle_ input() 這樣的回調。peer()返回指向
42、底層 PEER_STREAM的引用。服務處理器的PEER_STREAM 是在其open() 掛鉤方法被調用時就緒的。任何處理方法都可使用這個訪問器來獲取指向已連接的 IPC 機制的引用。3 3服務關閉方法服務關閉方法方法方法描述描述destroy()可以用來直接關閉服務處理器handle_close()通過來自反應器的回調調用 destroy() close()從服務處理器退出時調用 handle_close() 應用可以直接調用destroy()來關閉服務處理器。該方法執行了以下步驟:1)從反應器處移除處理器 2)取消任何與此處理器相關的定時器3)關閉對端流對象,以免發生句柄泄漏4)如果對象
43、是被動態分配的,將其刪除,以免內存泄漏。下面討論一下如何在代碼中使用ACE_Svc_Handler。1ACE_Svc_Handler是一個類模板,定義它的子類時,要指定模板的類型。PEER_STREAM: 底層傳遞數據流的類型,Socket 連接使用ACE_SOCK_StreamSYNCH_STRATEGY: 同步策略,可以使用ACE_NULL_SYNCH(無同步),ACE_MT_SYNCH(ACE 默認提供的同步策略) 。2子類覆蓋事件類型相應的handle_*()方法。3.2.2 ACE_AcceptorACE_Acceptor是一個工廠,它實現了Acceptor-Connector中的A
44、cceptor角色。也就是說起到了Server的作用。首先我們看一下ACE_Acceptor提供了那些接口:1 1初始化,析構及訪問器方法初始化,析構及訪問器方法CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199714/82方法方法描述描述ACE_Acceptor() open()將接受器的被動 IPC 端點綁定到特定地址,比如 TCP 端口或者 IPC 主機地址,然后對連接請求的到達進行監聽ACE_Acceptor() close()關閉接受器的 IPC 端點,并釋放資源。acceptor()返回指向底層 PEER_ACCEPTOR
45、的引用。2 2連接建立和服務處理器初始化方法連接建立和服務處理器初始化方法方法方法描述描述handle_input()當連接請求從對端連接器到達時,反應器會調用此模板方法。它可以使用在下面概述的3 個方法來使用“被動地連接 IPC 端點并創建和激活與其相關聯的服務處理器”所必需的各步驟自動化。make_svc_handler()該工廠方法創建服務處理器來處理通過其已連接的 IPC 端點,從對端服務發出的數據請求accept_svc_handler()該掛鉤方法使用接受器的被動模式 IPC 端點來創建已連接的 IPC 端點,并將此端點與和服務處理器相關聯的一個 I/O 句柄封裝在一起activa
46、te_svc_handler()該掛鉤方法調用服務處理器的 open() ,使服務處理器完成對自己的初始化。下面的順序圖詳細的描述了當連接請求到達時,ACE_Acceptor所做的工作:CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199715/82那么我們在應用程序中如何使用ACE_Acceptor呢?1首先,實現ACE_Svc_Handler子類,然后覆蓋相應的handle_*()事件回調方法。2沒有特殊需要的情況下,我們不需要創建ACE_Acceptor的子類,只須定義它的實例即可。ACE_Acceptor是一個類模板,定義它的實
47、例時,要指定模板的類型。SVC_Handler: 指定Acceptor對應的ACE_Svc_Handler,當有連接請求時,Acceptor會創建一個新的ACE_Svc_Handler來處理對端的事件。PEER_ACCEPTOR:它能夠被動的接受客戶連接,常被指定為 ACE 的各個 IPC Wrapper Faade。對于 Socket 來說,可以指定為ACE_SOCK_Acceptor。3使用Open()方法,即可啟動服務器,開始監聽客戶機事件。對于 Socket 來說,Open方法需要使用一個ACE_INET_Addr。3.2.3 ACE_Connector同ACE_Acceptor相同,
48、ACE_Connector也是一個工廠,它實現了Acceptor-Connector中的Connector角色。也就是說起到了Client的作用。ACE_Connector的接口有:1 1連接器初始化,析構方法以及訪問器方法連接器初始化,析構方法以及訪問器方法方法方法描述描述ACE_Connector() 用于初始化連接器的方法CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199716/82open()ACE_Connector() close()釋放連接器所用的資源connector()返回指向底層的 PEER_CONNECTOR的引
49、用2 2連接建立和服務處理器初始化方法連接建立和服務處理器初始化方法:可用于主動地建立連接,并對服務處理器進行初始化。方法方法描述描述connect()應用會在想要將某個服務處理器連接到監聽的對端時,調用這個模板方法。它可以使用下面的 3 個方法來使“主動連接某個 IPC 端點,創建并激活與其相關聯的服務處理器”所必需的各步驟自動化。make_svc_handler()該工廠方法提供服務處理器,后者會使用已連接的 IPC 端點connect_svc_handler()該掛鉤方法使用服務處理器的 IPC 端點來同步或異步地主動連接端點activate_svc_handler()該掛鉤方法調用服務
50、處理器的open() 掛鉤方法,后者允許服務處理器在連接建立之后完成對其自身的初始化。handle_output()在異步發起的連接請求完成之后,反應器會調用這個模板方法。它調用activate_svc_handler() 方法,以讓服務處理器對其自身進行初始化。cancel()取消某服務處理器,其連接之前是異步發起的。調用者不是連接器負責關閉服務處理器。與Acceptor有些不同的是,Connector在連接時可以選擇同步或異步連接。因為對于Acceptor來說,建立連接通常是即時的,而主動連接建立就要花較長的一段時間,尤其是廣域網。我們這里只討論同步連接的情形。下面的順序圖詳細的描述了異步
51、連接建立中的各步驟:CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199717/82 接下來討論一下在應用程序中如何使用ACE_Connector呢?(同ACE_Acceptor基本類似)1首先,實現ACE_Svc_Handler子類,然后覆蓋相應的handle_*()事件回調方法。2沒有特殊需要的情況下,我們也不需要創建ACE_Connector的子類,只須定義它的實例即可。ACE_Connector是一個類模板,定義它的實例時,要指定模板的類型。SVC_Handler: 指定Connector對應的ACE_Svc_Handler,同
52、服務器建立連接時,Connector會創建一個新的ACE_Svc_Handler來處理對端的事件。PEER_Connector:它能夠主動的建立客戶連接,常被指定為 ACE 的各個 IPC Wrapper Faade。對于 Socket 來說,可以指定為ACE_SOCK_Connector。3使用connect()方法去主動連接。connect方法里的參數有你剛才創建的ACE_Svc_Handler子類的指針和待連接的 PEER_Address(對于 Socket 來說,是ACE_INET_Addr)。3.3 ACE Reactor Server (Demo)3.3.1 需求需求下面我們實現一
53、個簡單的Server端,這個Server能夠處理多個Client的連接,在收到Client的消息后,原封不動的將消息再發還給Client。3.3.2 實現實現接下來我們一步一步實現它(在 RedHat 9,使用 Magic C+開發,最終的代碼可以在前面指定位置獲得):CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199718/821.使用 Magic C+在 Linux 服務器上建立一個新工程 ReactorServer2.如果系統不能從環境變量等找到 include 的 ACE 頭文件,那么你需要在項目設定的 Compile 項中指
54、定。比如 /home/work/ACE_wrappersCJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199719/823.在項目設定的 Link 的選項卡中,庫文件處加入 ACE 庫的支持。同上,如果系統不能從環境變量等找到ACE 庫文件,你也需要在下面的 Library directories 中指定。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199720/824.準備工作做好之后,下面我們創建 服務處理器。 創建新類 ServerHandler,繼承自ACE_Svc_H
55、andler。修改頭文件 ServiceHandler.h 。1)由于我們創建的是 Socket 服務器,ACE_Svc_Handler的模板里PEER_STREAM被指定為ACE_SOCK_STREAM, 同時我們不需要使用同步機制,模板里的SYNCH_STRATEGY被指定為ACE_NULL_SYNCH。class ServerHandler : public ACE_Svc_Handler2)我們只關心輸入事件,也就是客戶端發來的消息,覆蓋handle_input 方法。 virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HAND
56、LE);下面是 ServiceHandler.h 的完整代碼#ifndef SERVERHANDLER_H#define SERVERHANDLER_H#include ace/Svc_Handler.h#include ace/SOCK_Stream.hclass ServerHandler : public ACE_Svc_Handlerpublic: virtual int handle_input (ACE_HANDLE fd = ACE_INVALID_HANDLE);#endif5.下面我們來實現 ServiceHandler 的 handle_input 方法。修改 cpp 文件
57、 ServiceHandler.cpp。1)在handle_input方法里,我們定義了一個 4096 的 char 數組。并出始化該數組。const int INPUT_SIZE = 4096;char bufferINPUT_SIZE;memset(buffer, 0, INPUT_SIZE);2)然后使用底層的 peer 來接收收到的消息,recv返回了收到的消息的 recv_cnt = this-peer().recv( buffer, sizeof(buffer);3)如果 length = 0, 說明對端的連接被斷開,這時候應返回-1,指示反應器停止為此事件處
58、理器檢測已登記的事件。if (recv_cnt peer().send(buffer, recv_cnt);5)handle_input結束時,我們應該返回 0,當下次有消息到來時,仍能被此服務處理器處理。return 0;下面是 ServiceHandler.cpp 的完整代碼#include ServerHandler.hint ServerHandler:handle_input (ACE_HANDLE)const int INPUT_SIZE = 4096;char bufferINPUT_SIZE;memset(buffer, 0, INPUT_SIZE);int recv_cnt
59、= this-peer().recv( buffer, sizeof(buffer);if (recv_cnt peer().send(buffer, recv_cnt);return 0;6.最后我們實現 main 方法,增加 ReactorServer.cpp 文件1)在 main 方法,首先定義監聽的 IP 地址,對于我們的 Server 應用來說,只須指定監聽的端口即可。我們在 9000 端口監聽。(ACE_INET_Addr 后面介紹)ACE_INET_Addr port_to_accept(9000);2)定義我們的 Server,Acceptor模板類的 SVC_Handler
60、指定為我們剛剛實現的ServerHandler,PEER_ACCEPTOR 指定為ACE_SOCK_Acceptor。然后使用 open 方法開始監聽。CJ000028RAS-001開發指南 Made by Expert Team上海超捷系統集成有限公司,199722/82ACE_Acceptor server;if(server.open(port_to_accept) = -1) return -1;3)接下來運行 ACE_Reactor 事件循環。ACE_Reactor:instance()-run_reactor_event_loop();下面是 ReactorServer.cpp 的完整代碼
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中國家用電動扳手行業市場全景分析及前景機遇研判報告
- 設備裝配單位管理制度
- 設計開發評審管理制度
- 2025年中國機器人集成行業市場全景分析及前景機遇研判報告
- 診所衛生應急管理制度
- 診所藥房員工管理制度
- 試驗人員考核管理制度
- 財務費用報銷管理制度
- 財政罰款票據管理制度
- 貨場淘汰設備管理制度
- 文獻整理表格
- 初一幾何綜合練習題
- DBJ∕T 13-261-2017 福建省二次供水不銹鋼水池(箱)應用技術規程
- GB∕T 16422.3-2022 塑料 實驗室光源暴露試驗方法 第3部分:熒光紫外燈
- 中國歷史地理復習資料
- 05示例:玉米脫粒機的設計(含全套CAD圖紙)
- 冷庫項目施工組織設計方案
- 年中總結會策劃方案
- (最新)污水處理池施工方案
- 肺膿腫護理查房ppt課件
- 我要建一座王宮(正譜)
評論
0/150
提交評論