RMI和Socket的比較及區(qū)別
2010年3月30日 admin 發(fā)表評論 閱讀評論
本文的測試數(shù)據(jù)來自國外專家文檔,詳細(xì)介紹如下:
一般來說,基于CS(client-server)軟件架構(gòu)的開發(fā)技術(shù)有很多種。比較常用的有:基于socket的網(wǎng)絡(luò)編程、RPC、基于Java技術(shù)的RMI(當(dāng)然C#也有類似技術(shù))、CORBA等。在這里我們只是對基于socket的網(wǎng)絡(luò)編程與RMI作個(gè)對比,有助于我們了解它們各自的應(yīng)用領(lǐng)域,幫助我們在面對一個(gè)具體問題的時(shí)候選用適合的技術(shù)。另外,本文所做的討論可以認(rèn)為是脫離了語言層面的東西,只是對技術(shù)的本身做一個(gè)討論,無關(guān)乎你是用C++、C#或Java 在開發(fā)。
一、RMI技術(shù)簡介
本文就以Java為例,簡單介紹一下RMI技術(shù)。
從Java1.1開始,遠(yuǎn)程方法調(diào)用作為Java分布式對象技術(shù)成為Java核心的API之一(在java.rmi.* 包)。RMI的引入,使得Java程序之間能夠?qū)崿F(xiàn)靈活的,可擴(kuò)展的分布式通信。RMI允許Java對象存在于多個(gè)不同的地址空間,分布在不同的Java虛擬機(jī)上。每一個(gè)地址空間可以在同一臺主機(jī)上或者網(wǎng)絡(luò)上不同的計(jì)算機(jī)上。由于遠(yuǎn)程方法調(diào)用跨越不同的虛擬機(jī)邊界到不同的指定的地址空間,所以沒有對象共享的全局變量,這就需要對象序列化(Object Serialization)API,它使得Java對象能夠在不同的JVM之間傳遞。對象序列化是特別為Java的對象設(shè)計(jì)的,這就意味著Java程序中的對象可以作為對象參數(shù)存?。尚蛄谢膶ο蟊仨殞?shí)現(xiàn)Serializable接口)。結(jié)合RMI和對象序列化機(jī)制,就可以訪問越過本地Java虛擬機(jī)邊界的對象以及數(shù)據(jù)。通過RMI,可以調(diào)用遠(yuǎn)程對象的遠(yuǎn)程方法,而通過Java對象序列化機(jī)制可以將對象傳遞給這些方法。
最基本的Java模型并沒有提供將遠(yuǎn)程主機(jī)上的Java對象看作本地Java程序地址空間一部分的能力,而RMI禰補(bǔ)了這一不足。另外,由于Java與硬件平臺無關(guān)的特性,無論是同構(gòu)的系統(tǒng)還是異構(gòu)的系統(tǒng),RMI不需移植就可以順利運(yùn)行。
RMI為Java平臺的分布式計(jì)算提供了一個(gè)簡單而直接的模型。因?yàn)镴ava的RMI技術(shù)是基于Java平臺的,所以它將Java平臺的安全性和可移植性等優(yōu)點(diǎn)帶到了分布式計(jì)算中。RMI大大擴(kuò)展Java的網(wǎng)絡(luò)計(jì)算能力,它為編寫基于分布式對象技術(shù)的企業(yè)級Internet/Intranet應(yīng)用提供了強(qiáng)大的系統(tǒng)平臺支持。
二、基于socket的網(wǎng)絡(luò)編程
當(dāng)你使用socket進(jìn)行網(wǎng)絡(luò)應(yīng)用開發(fā)的時(shí)候,一般的思路是“消息驅(qū)動(dòng)邏輯”,即這樣的軟件系統(tǒng)一般具有以下特點(diǎn):
(1) 客戶端與服務(wù)器端依靠消息進(jìn)行通訊。
(2) 客戶端或者服務(wù)器端都需要一個(gè)消息派遣器,將消息投遞給具體的massage handler
(3) 客戶端或者服務(wù)器端利用massage handler進(jìn)行邏輯事務(wù)處理
三、RMI Vs Sochet
RMI技術(shù)比較socket的網(wǎng)絡(luò)編程主要有以下幾個(gè)方面:
第一、.RMI是面向?qū)ο蟮模笳卟皇恰?br> 第二、.RMI是與語言相綁定的。比如當(dāng)你使用Java RMI技術(shù)的時(shí)候,客戶端與服務(wù)器端都必須使用Java開發(fā)。而socket的網(wǎng)絡(luò)編程是使用獨(dú)立于開發(fā)語言的,甚至獨(dú)立于平臺?;趕ocket的網(wǎng)絡(luò)編程,客戶端與服務(wù)器端可以使用不同開發(fā)語言和不同的平臺。
第三、從網(wǎng)絡(luò)協(xié)議棧的觀點(diǎn)來看,RMI與socket的網(wǎng)絡(luò)編程處于不同層次上?;趕ocket的網(wǎng)絡(luò)編程位于TCP協(xié)議之上,而RMI在TCP協(xié)議之上,又定義了自己的應(yīng)用協(xié)議,其傳輸層采用的是Java遠(yuǎn)程方法協(xié)議(JRMP)。可見,在網(wǎng)絡(luò)協(xié)議棧上,基于RMI的應(yīng)用位置更高一些,這也決定了,與socket的網(wǎng)絡(luò)編程相比,RMI會(huì)喪失一些靈活性和可控性,但是好處是它帶給了應(yīng)用開發(fā)者更多的簡潔,方便和易用。比如:如果你用的是RMI,你不需要關(guān)心消息是怎么序列化的,你只需要像本地方法調(diào)用一樣,使用RMI。代價(jià)是:應(yīng)用開發(fā)者無法很好地控制消息的序列化機(jī)制。
第四、這是最后一點(diǎn)不同,我認(rèn)為也是比較重要的一點(diǎn),就是兩種方法的性能比較,其往往決定著你將使用那種技術(shù)來開發(fā)你的應(yīng)用。以下引用Adrian Reber在Network-programming with RMI文中對TCP和RMI所做的一個(gè)比較,其做的實(shí)驗(yàn)主要是對兩者在網(wǎng)絡(luò)傳輸?shù)膸捝献鞯膶Ρ龋?在網(wǎng)絡(luò)上傳輸2 byte的有效數(shù)據(jù),對于TCP而言,總共有478 byte被額外傳輸,而對于RMI, 1645byte被額外傳輸。
以下是兩者的trace結(jié)果:
TCP:
46037 > 12345 [SYN] Seq=801611567 Ack=0 Win=5840 Len=0
12345 > 46037 [SYN, ACK] Seq=266515894 Ack=801611568 Win=10136 Len=0
46037 > 12345 [ACK] Seq=801611568 Ack=266515895 Win=5840 Len=0
12345 > 46037 [PSH, ACK] Seq=266515895 Ack=801611568 Win=10136 Len=1
46037 > 12345 [ACK] Seq=801611568 Ack=266515896 Win=5840 Len=0
12345 > 46037 [FIN, PSH, ACK] Seq=266515896 Ack=801611568 Win=10136 Len=1
46037 > 12345 [RST, ACK] Seq=801611568 Ack=266515898 Win=5840 Len=0
RMI:
42749 > rmiregistry [SYN, ECN, CWR]
Seq=3740552479 Ack=0 Win=32767 Len=0
rmiregistry > 42749 [SYN, ACK, ECN]
Seq=3749262223 Ack=3740552480 Win=32767 Len=0
42749 > rmiregistry [ACK] Seq=3740552480 Ack=3749262224 Win=32767 Len=0
JRMI, Version: 2, StreamProtocol
rmiregistry > 42749 [ACK] Seq=3749262224 Ack=3740552487 Win=32767 Len=0
JRMI, ProtocolAck
42749 > rmiregistry [ACK] Seq=3740552487 Ack=3749262240 Win=32767 Len=0
Continuation
rmiregistry > 42749 [ACK] Seq=3749262240 Ack=3740552506 Win=32767 Len=0
JRMI, Call
rmiregistry > 42749 [ACK] Seq=3749262240 Ack=3740552556 Win=32767 Len=0
JRMI, ReturnData
42749 > rmiregistry [ACK] Seq=3740552556 Ack=3749262442 Win=32767 Len=0
JRMI, Ping
JRMI, PingAck
42749 > rmiregistry [ACK] Seq=3740552557 Ack=3749262443 Win=32767 Len=0
JRMI, DgcAck
42749 > rmiregistry [FIN, ACK]
Seq=3740552572 Ack=3749262443 Win=32767 Len=0
rmiregistry > 42749 [FIN, ACK]
Seq=3749262443 Ack=3740552573 Win=32767 Len=0
42749 > rmiregistry [ACK] Seq=3740552573 Ack=3749262444 Win=32767 Len=0
實(shí)驗(yàn)的結(jié)果是:RMI與TCP based socket相比,傳輸相同的有效數(shù)據(jù),RMI需要占用更多的網(wǎng)絡(luò)帶寬(protocol overhead)。從這里,我們可以得出一個(gè)一般性的結(jié)論:RMI主要是用于遠(yuǎn)程方法的”調(diào)用“(RMI是多么的名符其實(shí):)),其技術(shù)內(nèi)涵強(qiáng)調(diào)的是“調(diào)用”,基于此,我能想到的是:移動(dòng)計(jì)算,和遠(yuǎn)程控制,當(dāng)你的應(yīng)用不需要在client與server之間傳輸大量的數(shù)據(jù)時(shí),RMI是較好的選擇,它簡潔、易于開發(fā)。但是,一旦你的應(yīng)用需要在client與server之間傳輸大量的數(shù)據(jù),極端的,比如FTP應(yīng)用,則RMI是不適合的,我們應(yīng)該使用socket。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點(diǎn)擊舉報(bào)。