1、DCOM
COM的進程透明特性表現(xiàn)在組件對象和客戶程序即可以擁有各自的進程空間,也可以共享同一個進程空間,COM負責把客戶的調(diào)用正確傳到組件對象中,并保證參數(shù)傳遞的正確性。組件對象和客戶代碼不必考慮調(diào)用傳遞的細節(jié),只要按照一般的函數(shù)調(diào)用的方式實現(xiàn)即可。如果進一步拓展進程透明特性,考慮組件對象與客戶程序運行在不同計算機上的情形,把進程透明性拓展為位置透明性,形成分布式組件對象模型,簡稱為DCOM。
DCOM是COM的擴展,它可以支持不同計算機上組件對象與客戶程序之間或者組件對象之間的相互通信,這些計算機可以在局域網(wǎng)內(nèi)、廣域網(wǎng)上、 Internet上。對于客戶程序而言,組件程序所處的位置是透明的,我們不必編寫任何處理遠程調(diào)用的代碼,因此,DCOM也是COM的無縫擴展。 DCOM處理了底層網(wǎng)絡(luò)協(xié)議的所有細節(jié)。
2、從COM轉(zhuǎn)向DCOM
進程內(nèi)組件與客戶程序之間的通信過程比較簡單。本地進程外組件與客戶程序之間的通信并不是直接進行的,而是用到了操作系統(tǒng)支持的一些跨進程通信方法。
DCOM只是簡單地把本地跨進程通信用一個網(wǎng)絡(luò)協(xié)議傳輸過程來代替,只是中間數(shù)據(jù)傳遞的路線更長一些。當然,網(wǎng)絡(luò)通信比單機系統(tǒng)環(huán)境下的跨進程通信要脆弱得多,所以為了保證協(xié)作過程的可靠性以及程序?qū)Ξ惓J录膽?yīng)變能力,客戶程序和組件程序需要考慮更多的細節(jié)。
3、DCOM對象的定位
客戶程序調(diào)用COM庫的基礎(chǔ)創(chuàng)建函數(shù)(比如CoGetClassObject)創(chuàng)建遠程組件對象需要知道遠程機器名和對象CLSID。
有兩種方法可以得到遠程對象的機器名信息:一是在創(chuàng)建函數(shù)的參數(shù)中指定COSERVERINFO結(jié)構(gòu),二是使用DCOM配置工具指定遠程機器名。
COM庫的創(chuàng)建函數(shù)得到了遠程對象的位置信息后,再把對象創(chuàng)建的任務(wù)交給SCM,由SCM通過RPC與遠程機器進行通信。SCM(程序名為 Rpcss.exe)也是COM庫的一部分,但它是一個單獨的進程。SCM負責創(chuàng)建新的COM對象,也負責建立組件對象與客戶程序之間的連接。如果要創(chuàng)建遠程對象,它會通過RPC調(diào)用遠程機器上的SCM,由遠程機器上的SCM啟動組件進程,并創(chuàng)建組件對象,然后返回到客戶機器。
當然,遠程組件對象被創(chuàng)建之后,它在返回到客戶機器的途中,還要經(jīng)過列集和散集的處理,包括創(chuàng)建代理對象和裝載存根代碼等,這些處理與本地進程外組件對象的處理完全一致。一旦組件對象被創(chuàng)建完成之后,客戶與組件之間的通信不再經(jīng)過SCM,而是直接通過代理對象和存根對象以及COM庫提供的底層傳輸機制來完成。
4、列集與散集
列集與散集是實現(xiàn)COM組件對象跨進程特性的關(guān)鍵技術(shù),它包括標準列集法和自定義列集法。同樣的技術(shù)也適用于DCOM組件對象與客戶程序之間的通信,兩者的區(qū)別在于列集數(shù)據(jù)包的傳遞方式有所不同,對于本地組件對象使用LPC傳遞,而對于DCOM組件對象使用RPC傳遞。
DCOM提供了一套復雜的列集和散集機制,它建立在RPC的基礎(chǔ)上。由于RPC被定義為DCE(分布式計算系統(tǒng))標準的一部分,而DCE RPC定義了所有常用數(shù)據(jù)類型的數(shù)據(jù)表達方式,即網(wǎng)絡(luò)數(shù)據(jù)表示法(NDR,network data representation)。為了使存根代碼和代理對象能夠正確地對參數(shù)和返回結(jié)果進行列集和散集,它們應(yīng)該使用一致的數(shù)據(jù)表示法NDR,以便在不同的操作系統(tǒng)環(huán)境下也能夠遠程調(diào)用。
5、對象RPC
DCOM協(xié)議也被稱為對象RPC(ORPC,object remote procedure call),它建立在DCE RPC協(xié)議的基礎(chǔ)上,可用于各種基于組件的分布式系統(tǒng)。ORPC建立了一套面向?qū)ο蟮倪h程調(diào)用規(guī)范,指定了如何在網(wǎng)絡(luò)上進行調(diào)用、對對象的引用如何表示和如何維護。ORPC協(xié)議已經(jīng)被作為Internet草案遞交到IETF(Internet Engineering Task Force , Internet 工程部)。
在Internet或Intranet網(wǎng)絡(luò)環(huán)境下,ORPC仍使用標準的RPC數(shù)據(jù)包,附加上專用于DCOM的一些信息――接口指針標識符(IPID,interface point identifier)、版本信息和擴展信息――作為調(diào)用和返回的附加參數(shù)進行傳送,其中IPID表示調(diào)用被處理的遠程機器上特定對象的特定接口。 DCOM客戶程序必須周期性地“pinging”遠程機器上的對象,以便保證客戶與對象一直處于連接狀態(tài)。
6、DCOM特性
DCOM可以作為分布式應(yīng)用系統(tǒng)的基本架構(gòu),客戶程序與DCOM組件對象之間形成了客戶/服務(wù)器關(guān)系,進一步可構(gòu)成多層軟件模型。DCOM組件具有COM 組件的一些基本特性,包括重用性、語言無關(guān)性等。而位置透明性 是DCOM的一個基本特性。DCOM的其他特性如下:
(1)可伸縮性。一方面,DCOM利用操作系統(tǒng)本身的可伸縮性;另一方面,DCOM提供了靈活的配置方案,允許不同的組件對象允許在不同的服務(wù)器上,DCOM的位置透明性保證了這種變化可以不必修改組件源程序。
(2)可配置性。安裝和管理是分布式軟件系統(tǒng)的兩個重要環(huán)節(jié)。DCOM提供了一個圖形界面的配置工具程序(DCOMCNFG.EXE),可使客戶程序和組件程序在不改變代碼的情況下適應(yīng)不同的網(wǎng)絡(luò)環(huán)境。
(3)安全性。DCOM使用了Windows NT提供的可擴展安全性框架,在非NT平臺上實現(xiàn)的DCOM也包括了一個與NT兼容的安全提供器。DCOM實現(xiàn)的安全性分為訪問安全性和激活安全性,訪問安全性指定那些用戶可以調(diào)用組件對象,激發(fā)安全性指定哪些用戶可以在一個新進程中創(chuàng)建新的對象。
(4)協(xié)議無關(guān)性。
(5)平臺獨立性
7、對象激活
激活(activation)一個組件對象包括兩種情形:一是創(chuàng)建新的組件對象,二是建立已有組件對象與客戶之間的連接。
COM擴展到DCOM之后,遠程對象的創(chuàng)建過程有所不同。為了標識一個遠程對象,僅僅提供一個128位的GUID還不夠,還必須提供遠程對象所在的機器名,也稱為遠程服務(wù)器名“RemoteServerName”。
(1)創(chuàng)建DCOM組件方法一
通過DCOM配置工具指定遠程服務(wù)器名,這種方式使得DCOM組件具有位置透明性。在Windows系統(tǒng)平臺上,遠程服務(wù)器名字RemoteServerName值被保存在系統(tǒng)注冊表HKEY_CLASSES_ROOT\APPID鍵下。
從CLSID和AppID鍵的結(jié)構(gòu)可以看出,每個AppID可用于多個組件對象,通常它代表了由多個CLSID共享的進程,該進程中的所有對象共享同樣的配置信息,包括遠程服務(wù)器名以及安全信息。在DCOM中引入AppID概念可以避免太多的注冊表關(guān)鍵字。
(2)創(chuàng)建DCOM組件方法二
用第一種方法并不是總能滿足應(yīng)用的要求,有些應(yīng)用要求在程序運行過程中控制要連接的服務(wù)器,比如多人游戲程序、網(wǎng)絡(luò)遠程管理工具等。對于這樣的應(yīng)用,DCOM允許在創(chuàng)建函數(shù)中指定遠程服務(wù)器名字??梢灾付ㄟh程服務(wù)器名字的創(chuàng)建函數(shù):CoCreateInstanceEx、 CoGetClassObject、CoGetInstanceFromFile、CoGetInstanceFromeIStorage。
在程序中指定服務(wù)器名字的另外一個功能是實現(xiàn)分布式應(yīng)用系統(tǒng)的動態(tài)負載平衡。目前DCOM還很難以實現(xiàn)自動負載平衡特性,但我們可以建立一個分派服務(wù)組件對象,所有的客戶都創(chuàng)建指定機器上的分派服務(wù)組件對象,由它創(chuàng)建另一個真正實現(xiàn)應(yīng)用功能的遠程對象,在把此遠程對象返回給客戶程序,以后客戶程序不再使用分派服務(wù)組件對象,而直接調(diào)用遠程對象。而分派服務(wù)組件對象可以根據(jù)當前的負載狀態(tài),從一組服務(wù)器中選擇負載最輕的服務(wù)器作為目標,創(chuàng)建遠程對象。
8、遠程創(chuàng)建進程內(nèi)組件:代理進程(surrogate)
為了遠程運行進程內(nèi)組件即DLL組件,要求在遠程機器上有代理進程(surrogate process)。除了可以遠程啟動進程內(nèi)組件之外,代理進程還提供了下面的特性:
l 進程內(nèi)組件程序中的嚴重錯誤只影響代理進程,不會使客戶進程崩潰;
l 一個代理進程可以同時為多個客戶提供服務(wù);
l 客戶可以保護自己避免靠不住的組件程序代碼,只訪問組件程序提供的服務(wù);
l 在代理進程中運行進程內(nèi)服務(wù)可使DLL享有代理進程的安全性。
Windows引進了缺省的代理進程,以及編寫自定義代理進程的協(xié)議規(guī)范。缺省實現(xiàn)的代理進程是一個混合線程模型、偽COM服務(wù)程序。當多個DLL組件被裝入到單個代理進程時,該進程按照注冊表中指定的線程模型對每個DLL組件對象進行實例化。如果一個DLL組件對象支持兩種線程模型,則COM選擇自由線程模型。COM即可以控制DLL組件程序的卸載,也可以終止代理進程。
如果一個進程內(nèi)組件滿足下列條件,則它將被裝入代理進程:
l 系統(tǒng)注冊表中,在組件對象的CLSID關(guān)鍵字下必須要指定AppID值,以及對應(yīng)的AppID關(guān)鍵字;
l 客戶程序在創(chuàng)建對象實例時,必須設(shè)置CLSTX_LOCAL_SERVER標志;
l 組件對象的CLSID關(guān)鍵字下不指定LocalServer32、LocalServer、LocalService值;
l 組件對象的CLSID關(guān)鍵字包含InProvServer32子鍵;
l 在InProcServer32子鍵中指定的DLL文件必須存在;
l 組件對象對應(yīng)的AppID鍵下指定DllSurrogate值。
如果組件對象的CLSID鍵下的LocalServer、LocalServer32或LocalService值指示了EXE的存在,則EXE程序?qū)⒈粌?yōu)先執(zhí)行,COM不再啟動代理程序。
9、利用名字對象(moniker)連接到遠程對象實例
通常COM對象實例是不可相互替代到,或者說不可相互交換的。它通過自己特有的狀態(tài)區(qū)別于同一類的其他對象實例。
在第8章中介紹的COM命名和綁定機制對于遠程對象同樣適用。
10、連接管理——遠程對象生存期的控制
COM控制對象的生存期最基本的機制是引用計數(shù),利用IUnknown的AddRef和Release成員函數(shù)控制對象的生存期。DCOM優(yōu)化了遠程對象的AddRef和Release的調(diào)用。優(yōu)化過程使用了OXID(object exporter identifier ,對象管理標識符)對象。OXID是一個64位值,通過OXID可以把RPC串綁定調(diào)用到它們的目標IPID。但是,在執(zhí)行調(diào)用之前,調(diào)用進程必須把 OXID轉(zhuǎn)譯成為底層RPC可以解釋的一組綁定。
在每臺支持DCOM的機器上,都有一個被稱為OXID解析器(OXID Resolver)的服務(wù),它負責向客戶提供用于連接到OXID的RPC串綁定信息,也負責接收遠程發(fā)來的“pinging”信息。OXID解析器之間通過RPC進行通信,它實現(xiàn)了RPC接口IOXIDResolver(不是COM接口)。
11、連接管理——pinging機制
如果不考慮客戶進程可能會非正常終止,則利用遠程引用計數(shù)控制對象生存期已經(jīng)足夠了。為了檢測客戶程序是否非正常終止,DCOM提供了一種簡單的方法 “pinging”。在現(xiàn)在實現(xiàn)的DCOM版本中,pingPeriod=2(分)且numPingsToTimeOut=3,這些值不能被改變。
12、連接管理——連接點管理
許多實際的分布式應(yīng)用都需要在兩個對象之間進行雙向通信。由于DCOM是對COM的無縫擴展,在第6章中介紹的COM提供的連接點機制同樣適用于遠程對象的情形。
13、連接管理——連接傳遞
用分派服務(wù)組件對象來實現(xiàn)分布式應(yīng)用的負載平衡特性實際上用到了連接傳遞特性。
連接傳遞不等于遠程對象創(chuàng)建的傳遞,DCOM不支持位置透明方式下對象創(chuàng)建的傳遞過程,但可以利用連接傳遞特性,通過程序控制服務(wù)器名字的方式實現(xiàn)遠程對象創(chuàng)建的傳遞。
14、并發(fā)管理——線程模型
COM本身并沒有線程模型,可以認為COM借用了Windows操作系統(tǒng)提供的線程模型,Win32程序設(shè)計模型把線程分成UI線程和輔助線程,相對應(yīng)地,COM把線程分成套間線程和自由線程。套間線程使用CoInitialize API函數(shù)執(zhí)行COM庫的初始化,COM在套間線程內(nèi)部創(chuàng)建了一個隱藏的窗口,此窗口的窗口過程函數(shù)負責把客戶對套間中的組件對象的調(diào)用發(fā)送到正確的成員函數(shù)中。
15、并發(fā)管理——消息過濾器
COM和DCOM的線程模型使我們了解到了客戶程序與組件對象調(diào)用過程中的線程切換,但調(diào)用可能會阻塞程序,甚至使得客戶程序無法正常進行。為此,COM提供了消息過濾機制,它既可用于客戶程序,也可用于組件程序,允許它們對于入調(diào)用和出調(diào)用有所選擇。
COM把調(diào)用分為三類:第一種是同步調(diào)用,這是最常見的調(diào)用類型,客戶調(diào)用組件對象,一直等到對象執(zhí)行完所有功能后再返回;第二種是異步調(diào)用,客戶調(diào)用組件對象,但不等到對象執(zhí)行完功能就馬上返回,以后對象通過出接口通知客戶程序,這也就是我們在第6章介紹的可連接對象機制;第三種為輸入同步調(diào)用,被調(diào)用對象必須在放棄控制之前返回,以便保證用戶界面不受影響,也就是說,在調(diào)用執(zhí)行過程中,對象不能調(diào)用任何可能會進入消息循環(huán)的函數(shù)。
16、DCOM安全模型
DCOM安全性建立在底層安全提供器基礎(chǔ)上,有些操作系統(tǒng)可以支持多個安全提供器,DCOM和RPC也可以同時支持多個安全提供器。所有的安全提供器有一個共同點,它們提供了一種表示安全角色(一般為用戶賬號)的方法、一種鑒定安全角色(一般通過口令或私有鑰匙)的方法,以及管理安全角色和其鑒定數(shù)據(jù)的一套機制。
17、DCOM安全模型——安全性策略
(1)訪問安全性和激發(fā)安全性。
(2)對象的安全身份。
(3)保護數(shù)據(jù)。
(4)鑒定級別。
(5)模仿級別。
18、DCOM安全模型——安全性配置
DCOM提供了多種保護應(yīng)用程序的方法,一方面,DCOM可以強制使用安全性而不用任何對象或?qū)ο蟮目蛻舫绦蜃鋈魏喂ぷ鳎瑢ο蟮陌踩栽O(shè)置可以在外部配置并且DCOM會自動強制使用。另一方面,DCOM把它完整的安全性結(jié)構(gòu)暴露給開發(fā)者,因而客戶和對象都可以通過程序控制其安全策略。