分布式計算、云計算與大數(shù)據(jù) 第2版 課件 第2章 分布式計算編程基礎(chǔ)_第1頁
分布式計算、云計算與大數(shù)據(jù) 第2版 課件 第2章 分布式計算編程基礎(chǔ)_第2頁
分布式計算、云計算與大數(shù)據(jù) 第2版 課件 第2章 分布式計算編程基礎(chǔ)_第3頁
分布式計算、云計算與大數(shù)據(jù) 第2版 課件 第2章 分布式計算編程基礎(chǔ)_第4頁
分布式計算、云計算與大數(shù)據(jù) 第2版 課件 第2章 分布式計算編程基礎(chǔ)_第5頁
已閱讀5頁,還剩72頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第2章分布式編程基礎(chǔ)提綱進(jìn)程間通信Socket編程RMI編程P2P編程進(jìn)程間通信的定義分布式計算的核心技術(shù)是進(jìn)程間通信(interprocesscommunication,IPC),即在互相獨立的進(jìn)程(進(jìn)程是程序的運行時表示)間通信及共同協(xié)作以完成某項任務(wù)的能力。計算機(jī)1計算機(jī)2互聯(lián)網(wǎng)單播通信與組播通信在分布式計算中,兩個或多個進(jìn)程按約定的某種協(xié)議進(jìn)行IPC,此處協(xié)議是指數(shù)據(jù)通信各參與進(jìn)程必須遵守的一組規(guī)則。在協(xié)議中,一個進(jìn)程有些時候可能是發(fā)送者,在其他時候則可能是接收者。單播組播IPC設(shè)施系統(tǒng)級IPC設(shè)施消息隊列共享內(nèi)存。。。高層的IPCAPI抽象開發(fā)分布式應(yīng)用往往工作量比較大且復(fù)雜更好地把注意力集中在應(yīng)用邏輯上API:ApplicationProgrammingInterface,應(yīng)用編程接口或應(yīng)用程序接口IPCAPI的四種基本操作發(fā)送(Send):該操作由發(fā)送進(jìn)程發(fā)起,旨在向接收進(jìn)程傳輸數(shù)據(jù)。操作必須允許發(fā)送進(jìn)程識別接收進(jìn)程和定義待傳數(shù)據(jù)。接收(Receive):該操作由接收進(jìn)程發(fā)起,旨在接收發(fā)送進(jìn)程發(fā)來的數(shù)據(jù)操作必須允許接收進(jìn)程識別發(fā)送進(jìn)程和定義保存數(shù)據(jù)的內(nèi)存空間,該內(nèi)存隨后被接收者訪問。連接(Connect):對面向連接的IPC,必須有允許在發(fā)起進(jìn)程和指定進(jìn)程間建立邏輯連擊的操作:其中以進(jìn)程發(fā)出請求連接操作而另一進(jìn)程發(fā)出接受連接操作。斷開連接(Disconnect):對面向連接的IPC,該操作允許通信的雙方關(guān)閉先前建立起來的某一邏輯連接。IPC使用示例:HTTP事件同步IPC中的一個主要難點是進(jìn)行IPC的各相關(guān)進(jìn)程是獨立執(zhí)行的,各進(jìn)程不知道對方進(jìn)程的情況。協(xié)議涉及的雙方必須按特定順序發(fā)起IPC操作,否則可能通信失敗。因此,參與通信的兩個進(jìn)程需要同步他們的操作,由一方發(fā)送數(shù)據(jù),另一方則需要等待所有數(shù)據(jù)發(fā)送完成時,開始接收數(shù)據(jù)。IPC設(shè)施提供事件同步的最簡單的方法是使用阻塞(blocking)機(jī)制或同步(synchronous),即掛起某一進(jìn)程的執(zhí)行,直到該進(jìn)程發(fā)起的某個操作執(zhí)行結(jié)束。另外,IPC操作可以是異步(asynchronous)或非阻塞操作(nonblocking)。進(jìn)程發(fā)起的異步操作不會引起阻塞。因此,一旦向IPC設(shè)施發(fā)出異步操作后,進(jìn)程可以繼續(xù)執(zhí)行。當(dāng)該異步操作完成后,進(jìn)程才會隨后得到IPC設(shè)施的通知。IPC范型在最低抽象層,IPC利用底層的串行或并行數(shù)據(jù)傳輸機(jī)制,在連接上傳輸二進(jìn)制流。例如,這種IPC范型可以用于編寫網(wǎng)絡(luò)驅(qū)動軟件。這種形式的IPC屬于網(wǎng)絡(luò)或操作系統(tǒng)編程領(lǐng)域。下一個抽象層是眾所周知的一種范型,稱作socket應(yīng)用程序接口(socketAPI)。在socket范型中,兩個進(jìn)程使用名為socket的邏輯構(gòu)造交換數(shù)據(jù),每一方都要建立一個socket。待發(fā)送數(shù)據(jù)被寫入socket。在另一端,接收進(jìn)程從自身的socket中讀取或提取數(shù)據(jù)。遠(yuǎn)程過程調(diào)用(remoteprocedurecall)或遠(yuǎn)程方法調(diào)用(remotemethodinvocation)范型通過允許向遠(yuǎn)程進(jìn)程發(fā)送過程調(diào)用或方法調(diào)用,來提供更高層次的抽象。這是,數(shù)據(jù)作為參數(shù)和返回值,在兩個進(jìn)程間進(jìn)行傳遞。提綱進(jìn)程間通信Socket編程RMI編程P2P編程Socket歷史SocketAPI最早作為BerkeleyUnix操作系統(tǒng)的程序庫,出現(xiàn)于20世紀(jì)80年代早期,用于提供IPC功能?,F(xiàn)在所有主流操作系統(tǒng)都支持SocketAPI。在BSD、Linux等基于Unix的系統(tǒng)中,SocketAPI都是操作系統(tǒng)的一部分。在個人計算機(jī)操作系統(tǒng)如MS-DOS、WindowsNT、Mac-OS、OS\2中,SocketAPI都是以程序庫形式提供的(在Windows系統(tǒng)中,SocketAPI稱為Winsocket)。Java語言在設(shè)計之初就考慮到了網(wǎng)絡(luò)編程,也將SocketAPI作為語言核心類的一部分提供給用戶。所有這些API都使用相同的消息傳遞模型和非常類似的語法。Socket現(xiàn)狀SocketAPI是實現(xiàn)進(jìn)程間通信的第一種編程設(shè)施。SocketAPI非常重要的原因主要有以下兩點:1)SocketAPI已經(jīng)成為IPC編程事實上的標(biāo)準(zhǔn),高層IPC設(shè)施都是構(gòu)建于SocketAPI之上的,即它們基于SocketAPI實現(xiàn)的。2)對于響應(yīng)時間要求較高或在有限資源平臺上運行的應(yīng)用來說,用SocketAPI實現(xiàn)是最合適的?;維ocket機(jī)制兩種主要的傳輸層協(xié)議UDP(UserDatagramProtocol,用戶數(shù)據(jù)包協(xié)議):允許使用無連接通信傳輸報文(即在傳輸層發(fā)送和接受)。被傳輸報文稱為數(shù)據(jù)報(datagram)。根據(jù)無連接通信協(xié)議,每個傳輸?shù)臄?shù)據(jù)包都被分別解析和路由,并且可按任何順序到達(dá)接收者。TCP(TransmissionControlProtocol,傳輸控制協(xié)議):面向連接的協(xié)議,它通過在接受者和發(fā)送者之間建立的邏輯連接來傳輸數(shù)據(jù)流。由于有連接,從發(fā)送者到接受者的數(shù)據(jù)能保證以與發(fā)送次序相同的順序被接受。兩種主要的傳輸層協(xié)議UDP:如果主機(jī)A上的進(jìn)程1通過順序傳輸數(shù)據(jù)包m1、m2,向主機(jī)B上的進(jìn)程2發(fā)送消息,這些數(shù)據(jù)包可以通過不同路由在網(wǎng)絡(luò)上傳輸,并且可按下列任何一種順序到達(dá)接收進(jìn)程:m1-m2或m2-m1。在數(shù)據(jù)通信網(wǎng)絡(luò)的術(shù)語中,“包”(或稱分組,英文為packet)是指在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)單位。每個包中都包含有效數(shù)據(jù)(載荷,payload)以及一些控制信息(頭部信息),如目的地址。TCP:如果主機(jī)A上的進(jìn)程1順序傳輸m1、m2,向主機(jī)B上的進(jìn)程2發(fā)送消息,接收進(jìn)程可以認(rèn)為消息將以m1-m2順序到達(dá),而不是m2-m1。兩種類型的Socket根據(jù)傳輸層所使用協(xié)議不同,SocketAPI分成兩種類型:數(shù)據(jù)包Socket:即DatagramSocket,一種使用UDP傳輸?shù)腟ocket。流式Socket:即StreamSocket,使用TCP傳輸?shù)腟ocket。提示:由于分布式計算與網(wǎng)絡(luò)應(yīng)用主要使用流式Socket比較多,后面將重點討論流式Socket的開發(fā)技術(shù)。兩種類型的SocketAPI數(shù)據(jù)報Socket(DatagramSocket)流式Socket(StreamSocket)流式SocketAPIJava流式Socket

API在Java中,有兩個類提供了流式SocketAPI:1)ServerSocket用于接受連接,我們將稱之為連接socket2)Socket用于數(shù)據(jù)交換,我們將稱之為數(shù)據(jù)socket流式Socket程序流類ServerSocket的主要方法和構(gòu)造函數(shù)Method/constructorDescriptionServerSocket(int

port)Createsaserversocketonaspecifiedport.Socketaccept()throwsIOExceptionListensforaconnectiontobemadetothissocketandacceptsit.Themethodblocksuntilaconnectionismade.publicvoidclose()throwsIOException

Closesthissocket.voidsetSoTimeout(int

timeout)throwsSocketExceptionSetatimeoutperiod(inmilliseconds)sothatacalltoaccept()forthissocketwillblockforonlythisamountoftime.Ifthetimeoutexpires,ajava.io.InterruptedIOExceptionisraised類Socket的主要方法和構(gòu)造函數(shù)Method/constructorDescriptionSocket(InetAddress

address,int

port)CreatesastreamsocketandconnectsittothespecifiedportnumberatthespecifiedIPaddressvoidclose()throwsIOExceptionClosesthissocket.InputStreamgetInputStream()throwsIOExceptionReturnsaninputstreamsothatdatamaybereadfromthissocket.OutputStream

getOutputStream()throwsIOExceptionReturnsanoutputstreamsothatdatamaybewrittentothissocket.voidsetSoTimeout(int

timeout)throwsSocketExceptionSetatimeoutperiodforblockingsothataread()callontheInputStreamassociatedwiththisSocketwillblockforonlythisamountoftime.Ifthetimeoutexpires,ajava.io.InterruptedIOExceptionisraised流式Socket基本語法//instantiatesasocketforacceptingconnectionServerSocketconnectionSocket=newServerSocket(portNo);SocketdataSocket=connectionSocket.accept();//getaoutputstreamforwritingtothedatasocketOutputStreamoutStream=dataSocket.getOutputStream();PrintWritersocketOutput=newPrintWriter(newOutputStreamWriter(outStream));socketOutput.println(message);socketOutput.flush();dataSocket.close();connectionSocket.close();//instantiatesadatasocketandconnectwithatimeoutSocketAddress

sockAddr=newInetSocketAddress(acceptorHost,acceptorPort);SocketmySocket=newSocket();inttimeoutPeriod=2000;//2secondsmySocket.connect(sockAddr,timeoutPeriod);//getaninputstreamforreadingfromthedatasocketInputStreaminStream=mySocket.getInputStream();BufferedReader

socketInput=newBufferedReader(newInputStreamReader(inStream));Stringmessage=socketInput.readLine();mySocket.close();類Example1ConnectionAcceptor類Example1ConnectionRequestor流式Socket基本語法在本例中有一些值得關(guān)注的地方:1)由于這里處理的是數(shù)據(jù)流,因此可使用Java類PrinterWriter向socket寫數(shù)據(jù)和使用BufferedReader從流中讀取數(shù)據(jù)。這些類中所使用的方法與向屏幕寫入一行或從鍵盤讀取一行文本相同。2)盡管本例將Acceptor和Requestor分別作為數(shù)據(jù)發(fā)送者和數(shù)據(jù)接收者介紹,但兩者的角色可以很容易地進(jìn)行互換。在那種情況下,Requestor將使用getOutputStream向socket中寫數(shù)據(jù),而Acceptor將使用getInputStream從socket中讀取數(shù)據(jù)。3)事實上,任一進(jìn)城都可以通過調(diào)用getInputStream和getOutputStream從流中讀取數(shù)據(jù)或向其中寫入數(shù)據(jù)。4)在本例中,每次只讀寫一行數(shù)據(jù)(分別使用readLine和println方法),但其實也可以每次只讀寫一行中的一部分?jǐn)?shù)據(jù)(分別使用read和print方法來實現(xiàn))。然而,對于以文本形式交換消息的文本協(xié)議來說,每次讀寫一行是標(biāo)準(zhǔn)做法。事件狀態(tài)圖隱藏數(shù)據(jù)Socket細(xì)節(jié)publicclassExample2ConnectionAcceptor{publicstaticvoidmain(String[]args){…

ServerSocketconnectionSocket=newServerSocket(portNo);MyStreamSocketdataSocket=newMyStreamSocket(connectionSocket.accept());dataSocket.sendMessage(message);dataSocket.close();connectionSocket.close();…}//endmain}//endclass類Example2ConnectionAcceptor類Example2ConnectionRequestorpublicclassExample2ConnectionRequestor{publicstaticvoidmain(String[]args){…

MyStreamSocket

mySocket=newMyStreamSocket(acceptorHost,acceptorPort);Stringmessage=mySocket.receiveMessage();

mySocket.close();…}//endmain}//endclassMyStreamSocket類實現(xiàn)細(xì)節(jié)publicclassMyStreamSocketextendsSocket{privateSocketsocket;privateBufferedReaderinput;privatePrintWriteroutput;

MyStreamSocket(InetAddress

acceptorHost,intacceptorPort)throwsSocketException,IOException{socket=newSocket(acceptorHost,acceptorPort);

setStreams();}

MyStreamSocket(Socketsocket)throwsIOException{

this.socket=socket;

setStreams();}privatevoidsetStreams()throwsIOException{//getaninputstreamforreadingfromthedatasocket

InputStream

inStream=socket.getInputStream();input=newBufferedReader(newInputStreamReader(inStream));

OutputStream

outStream=socket.getOutputStream();output=newPrintWriter(newOutputStreamWriter(outStream));//createaobjectforcharacter-modeoutput}publicvoidsendMessage(Stringmessage)throwsIOException{

output.println(message);

output.flush();}//endsendMessagepublicStringreceiveMessage()throwsIOException{//readalinefromthedatastreamStringmessage=input.readLine();returnmessage;}//endreceiveMessage}//endclass提綱進(jìn)程間通信Socket編程RMI編程P2P編程RMI的定義RMI是RemoteMethodInvocation的縮寫,即遠(yuǎn)程方法調(diào)用。RMI是RPC模型的面向?qū)ο髮崿F(xiàn),是一種用于實現(xiàn)遠(yuǎn)程過程調(diào)用的應(yīng)用程序編程接口,它使客戶機(jī)上運行的程序可以調(diào)用遠(yuǎn)程服務(wù)器上的對象。JavaRMI由于RMIAPI只適用于Java程序,所以,我們一般稱為JavaRMI。但該API相對簡單,因此,非常適合于用作學(xué)習(xí)網(wǎng)絡(luò)應(yīng)用中分布式對象技術(shù)的入門資料。

JavaRMI使用接口化編程。在需要服務(wù)端的某一個遠(yuǎn)程對象時,編程人員通過定義一個該對象的接口來隱藏它的實現(xiàn),并在客戶端定義一個相同的接口,客戶端使用該接口可以像本地調(diào)用一樣實現(xiàn)遠(yuǎn)程方法調(diào)用。通過調(diào)用RMI的API,對象服務(wù)器通過目錄服務(wù)導(dǎo)出和注冊遠(yuǎn)程對象,這些對象提供一些可以被客戶程序調(diào)用的遠(yuǎn)程方法。從語法上來看,RMI通過遠(yuǎn)程接口聲明遠(yuǎn)程對象,該接口是Java接口的擴(kuò)展;遠(yuǎn)程接口由對象服務(wù)器實現(xiàn);對象客戶使用與本地方法調(diào)用類似的語法訪問遠(yuǎn)程對象,并調(diào)用遠(yuǎn)程對象的方法。JavaRMI體系結(jié)構(gòu)從應(yīng)用層看,RMI由客戶應(yīng)用、服務(wù)器應(yīng)用和對象目錄服務(wù)3個部分。RMI系統(tǒng)實現(xiàn)架構(gòu)由三層組成:樁/框架(Stub/Skeleton)層:客戶端的樁和服務(wù)器端的框架;遠(yuǎn)程引用(remotereference)層:處理遠(yuǎn)程引用行為;傳輸層(transport):連接的建立和管理,以及遠(yuǎn)程對象的跟蹤。RMI基本分布式應(yīng)用遠(yuǎn)程接口定義服務(wù)器端軟件客戶端軟件RMI基本分布式應(yīng)用:遠(yuǎn)程接口定義在RMIAPI中,分布式對象的創(chuàng)建開始于遠(yuǎn)程接口。Java接口是為其他類提供模板的一種類:它包括方法聲明或簽名,其實現(xiàn)由實現(xiàn)該接口的類提供。Java遠(yuǎn)程接口是繼承Java類remote的一個接口,該類允許使用RMI語法實現(xiàn)接口。與必須為每個方法簽名定義擴(kuò)展和RemoteException不同,遠(yuǎn)程接口語法與常規(guī)或本地Java接口相同。RMI基本分布式應(yīng)用:遠(yuǎn)程接口定義importjava.rmi.*;publicinterfaceSomeInterface

extendsRemote{//signatureoffirstremotemethodpublicStringsomeMethod1()throwsjava.rmi.RemoteException;//signatureofsecondremotemethodpublicintsomeMethod2(intx)throwsjava.rmi.RemoteException;//signatureofotherremotemethodsmayfollow}//endinterfaceRMI基本分布式應(yīng)用:服務(wù)器端軟件對象服務(wù)器是指這樣的一種對象,它可以提供某一分布式對象的方法和接口。每個對象服務(wù)器必須:1)實現(xiàn)接口部分定義的每個遠(yuǎn)程方法;2)向目錄服務(wù)注冊包含了實現(xiàn)的對象。RMI基本分布式應(yīng)用:服務(wù)器端軟件import

java.rmi.*;import

java.rmi.server.*;publicclassSomeImplextendsUnicastRemoteObject

implementsSomeInterface{publicStringsomeMethod1()throwsRemoteException{//codetobesupplied}publicintsomeMethod2()throwsRemoteException{//codetobesupplied}}//endclass1)遠(yuǎn)程接口實現(xiàn)遠(yuǎn)程接口實現(xiàn)類的一個通用模板RMI基本分布式應(yīng)用:服務(wù)器端軟件1)遠(yuǎn)程接口實現(xiàn)import

java.rmi.*;import

java.rmi.server.*;publicclassHelloImplextendsUnicastRemoteObjectimplementsHelloInterface{publicHelloImpl()throwsRemoteException{super();}publicStringsayHello(Stringname)throwsRemoteException{return"WELCOMETORMI!Goodafternoon!"+name+".";}}//endclassRMI基本分布式應(yīng)用:服務(wù)器端軟件1)遠(yuǎn)程接口實現(xiàn)RMI基本分布式應(yīng)用:服務(wù)器端軟件2)stub和skeleton生成在RMI中,分布式對象需要為每個對象服務(wù)器和對象客戶提供代理,分別成為對象skeleton和stub。這些代理可通過使用JavaSDK提供的RMI編譯器rmic,編譯遠(yuǎn)程接口實現(xiàn)生成??稍诿钚邢螺斎胂率雒钌蓅tub和skeleton文件:rmic<classnameoftheremoteinterfaceimplementation>例如:rmicSomeImplRMI基本分布式應(yīng)用:服務(wù)器端軟件2)stub和skeleton生成如果編譯成功,將生成兩個代理文件,每個文件的名都以實現(xiàn)類的類名為前綴:SomeImpl_stub.classSomeImpl_skel.class但在Java2版本以上的平臺下,只生成stub文件。對象的stub文件及遠(yuǎn)程接口文件,必須被每個對象客戶所共享:這些文件是編譯客戶程序時所必須的文件。可以手工為對象客戶提供每個文件的一個拷貝。此外JavaRMI具有stub下載特征,允許客戶端動態(tài)獲取stub文件。RMI基本分布式應(yīng)用:服務(wù)器端軟件3)對象服務(wù)器的實現(xiàn)SomeImplexportedObj=newSomeImpl();startRegistry(1234);registryURL="rmi://localhost:"+portNum+"/some";Naming.rebind(registryURL,exportedObj);listRegistry(registryURL);主機(jī)名

端口號引用名類Naming提供從注冊表獲取和存儲引用的方法。具體來說,rebind方法允許如下形式URL將對象引用存儲到注冊表中:主機(jī)名應(yīng)該是服務(wù)器名,或簡寫成localhost,引用名指用戶選擇的名稱,該名稱在注冊表中應(yīng)該是惟一的。rebind方法將覆蓋注冊表中與給定引用名綁定的任何引用。如果不希望覆蓋,可以使用bind方法。URL:rmi://<hostname>:<portnumber>/<referencename>//檢查RMI注冊表當(dāng)前是否運行在默認(rèn)端口上。如果不在,RMI注冊表將被激活。RMI基本分布式應(yīng)用:服務(wù)器端軟件3)對象服務(wù)器的實現(xiàn)此外,可以使用JDK中的rmiregistry工具在系統(tǒng)提示符輸入下列命令,手工激活RMI注冊表:rmiregistry<portnumber>

端口號(默認(rèn)1099)RMI對象服務(wù)器是并發(fā)服務(wù)器:每個對象客戶請求都使用服務(wù)器上的一個獨立線程服務(wù)。由于遠(yuǎn)程方法調(diào)用可并發(fā)執(zhí)行,因此遠(yuǎn)程對象實現(xiàn)的線程安全性非常重要。RMI基本分布式應(yīng)用:服務(wù)器端軟件3)對象服務(wù)器的實現(xiàn)RMI基本分布式應(yīng)用:客戶端軟件查找遠(yuǎn)程對象:如果對象服務(wù)器先前在注冊表中保存了對象引用,可以用類Naming的lookup方法獲取這些引用。注意,應(yīng)將獲取的引用傳給遠(yuǎn)程接口類。StringregistryURL="rmi://localhost:"+portNum+"/some";SomeInterfaceh=(SomeInterface)Naming.lookup(registryURL);調(diào)用遠(yuǎn)程方法:遠(yuǎn)程接口引用可以調(diào)用遠(yuǎn)程接口中的任何方法,例如:Stringmessage=h.method1();System.out.println(message);注意,調(diào)用遠(yuǎn)程方法的語法與調(diào)用本地方法相同。RMI應(yīng)用構(gòu)建步驟總結(jié)1)服務(wù)器端軟件開發(fā)算法為該應(yīng)用的所有待生成文件創(chuàng)建一個目錄。在SomeInterface.java中定義遠(yuǎn)程服務(wù)器接口。編譯并修改程序,直到不再有任何語法錯誤。SomeImpl.java中實現(xiàn)接口,編譯并修改程序,直到不再有任何語法錯誤。使用RMI編譯器rmic處理實現(xiàn)類,生成遠(yuǎn)程對象的stub文件

rmicSomeImpl可以從目錄中看到新生成文件SomeImpl_Stub.class,每次修改接口實現(xiàn)時,都要重新執(zhí)行步驟3和步驟4創(chuàng)建對象服務(wù)器程序SomeServer.java,編譯并修改程序,直到不再有任何語法錯誤。激活對象服務(wù)器javaSomeServerRMI應(yīng)用構(gòu)建步驟2)客戶端軟件開發(fā)算法為該應(yīng)用的所有待生成文件創(chuàng)建一個目錄獲取遠(yuǎn)程接口類文件的一個拷貝,也可獲取遠(yuǎn)程接口源文件的一個拷貝,使用javac編譯程序,生成接口文件。獲取接口實現(xiàn)stub文件SomeImpl_stub.class的一個拷貝開發(fā)客戶程序SomeClient.java,編譯程序,生成客戶類激活客戶javaSomeClientRMI應(yīng)用構(gòu)建步驟2)客戶端軟件開發(fā)算法客戶類程序與任何其他Java類相似。RMI所需的語法包括定位服務(wù)器主機(jī)的RMI注冊表和查找服務(wù)器對象的遠(yuǎn)程引用;該引用隨后可被傳到遠(yuǎn)程接口類和被調(diào)用的遠(yuǎn)程方法查找遠(yuǎn)程對象:如果對象服務(wù)器先前在注冊表中保存了對象引用,可以用類Naming的lookup方法獲取這些引用。注意,應(yīng)將獲取的引用傳給遠(yuǎn)程接口類。

StringregistryURL="rmi://localhost:"+portNum+"/some";

SomeInterfaceh=(SomeInterface)Naming.lookup(registryURL);調(diào)用遠(yuǎn)程方法:遠(yuǎn)程接口引用可以調(diào)用遠(yuǎn)程接口中的任何方法,例如:

Stringmessage=h.method1();System.out.println(message);注意,調(diào)用遠(yuǎn)程方法的語法與調(diào)用本地方法相同。RMI應(yīng)用構(gòu)建步驟2)客戶端軟件開發(fā)算法基本RMI應(yīng)用程序演示RMI應(yīng)用的HelloWorld實現(xiàn)程序:HelloInterface.javaHelloImpl.javaHelloServer.javaHelloClient.javaHelloWorld程序演示RMI應(yīng)用構(gòu)建步驟3)測試和調(diào)試構(gòu)建最小RMI程序的一個模板。從一個遠(yuǎn)程接口開始,其中包括一個方法簽名,一個stub實現(xiàn),一個輸出對象的服務(wù)器程序以及一個足以用來調(diào)用遠(yuǎn)程方法的客戶程序。在單機(jī)上測試模板程序,直到遠(yuǎn)程方法調(diào)用成功。每次在接口中增加一個方法簽名。每次增加后都修改客戶程序來調(diào)用新增方法。完善遠(yuǎn)程方法定義內(nèi)容,每次只修改一個。在繼續(xù)下一個方法之前,測試并徹底調(diào)試每個新增方法。完全測試所有遠(yuǎn)程方法后,采用增量式方法開發(fā)客戶應(yīng)用。每次增加后,都測試和調(diào)試程序。將程序部署到多臺機(jī)器上,測試并調(diào)試。RMI和socketAPI的比較遠(yuǎn)程方法調(diào)用API作為分布式對象計算范型的代表,是構(gòu)建網(wǎng)絡(luò)應(yīng)用的有效工具。它可用來取代socketAPI快速構(gòu)建網(wǎng)絡(luò)應(yīng)用。在RMIAPI和socketAPI之間權(quán)衡時,需要考慮以下因素:1)socketAPI的執(zhí)行與操作系統(tǒng)密切相關(guān),因此執(zhí)行開銷更小,RMI需要額外的中間件支持,包括代理和目錄服務(wù),這些不可避免地帶來運行時開銷。對有高性能要求的應(yīng)用來說,socketAPI仍將是惟一可行途徑。2)RMIAPI提供了使軟件開發(fā)任務(wù)更為簡單的抽象。用高級抽象開發(fā)的程序更易理解,因此也更易調(diào)試。RMI和socketAPI的比較由于運行在低層,socketAPI通常是平臺和語言獨立的,RMI則不一定。例如JavaRMI需要特定的Java運行時支持。結(jié)果是,使用JavaRMI實現(xiàn)的應(yīng)用必須用Java編寫,并且也只能運行在Java平臺上。在設(shè)計應(yīng)用系統(tǒng)時,是否能選擇適當(dāng)?shù)姆缎秃虯PI是非常關(guān)鍵的。依賴于具體環(huán)境,可以在應(yīng)用的某些部分使用某種范型或API,而在其他部分使用另一種范型或API。由于使用RMI開發(fā)網(wǎng)絡(luò)應(yīng)用相對簡單,RMI是快速開發(fā)應(yīng)用原型的一個很好的候選工具。提綱進(jìn)程間通信Socket編程RMI編程P2P編程P2P的定義P2P,即Peer-to-Peer的縮寫,常稱它為“點對點”或者“端對端”,而學(xué)術(shù)界常稱它為“對等計算”。P2P是一種以非集中化方式使用分布式資源來完成計算任務(wù)的一種分布式計算模式。非集中化:P2P系統(tǒng)中并非采用傳統(tǒng)的以服務(wù)器為中心管理所有客戶端的方法,而是消除“中心”的概念,將原來的客戶端視為服務(wù)器和客戶端的綜合體;分布式資源:P2P系統(tǒng)的參與者共享自己的一部分空閑資源供系統(tǒng)處理關(guān)鍵任務(wù)所用,這些資源包括處理能力、數(shù)據(jù)文件、數(shù)據(jù)存儲和網(wǎng)絡(luò)帶寬等。P2P的優(yōu)點P2P技術(shù)打破了傳統(tǒng)的Client/Server(縮寫為C/S)模式,在P2P網(wǎng)絡(luò)中所有結(jié)點的地位都是對等的,每個結(jié)點既充當(dāng)服務(wù)器,又充當(dāng)客戶端,這樣緩解了中心服務(wù)器的壓力,使得資源或任務(wù)處理更加的分散化。由于P2P網(wǎng)絡(luò)中結(jié)點是Client和Server的綜合體,因此結(jié)點也被形象地稱為“SERVENT”。C/S模式與P2P模式對比C/S模式P2P模式C/S模式與P2P模式對比C/S模式:服務(wù)器和客戶端之間是一對多的主從關(guān)系,系統(tǒng)的信息和數(shù)據(jù)都保存在中心服務(wù)器上若要索取信息,必須先訪問服務(wù)器,才能得到所需的信息,且客戶端之間是沒有交互能力的。P2P模式:不區(qū)分提供信息的服務(wù)器和請求信息的客戶端,每一個結(jié)點都是信息的發(fā)布者和請求者,對等結(jié)點之間可以實現(xiàn)自治交互,無需使用服務(wù)器。每個對等結(jié)點都可以在網(wǎng)絡(luò)中發(fā)布和分享信息,使得網(wǎng)絡(luò)中閑散的資源得到充分利用。不需要花費高昂的費用來維護(hù)中心服務(wù)器?;赑2P范型的即時聊天系統(tǒng)開發(fā)由于演示的是簡單的P2P即時聊天系統(tǒng),所以,我們僅僅設(shè)計了如下幾個功能:(1)點對點單人聊天;(2)多人同時在線聊天;(3)用戶可以自由加入和退出系統(tǒng);(4)具備用戶在線狀態(tài)監(jiān)視。1)確定系統(tǒng)實現(xiàn)功能為了更好地理解P2P分布式計算模式和P2P應(yīng)用的開發(fā)方法,本節(jié)使用JavaSocket來實現(xiàn)一個簡單的基于P2P范型的即時聊天系統(tǒng)。系統(tǒng)的功能基于P2P范型的即時聊天系統(tǒng)開發(fā)為了簡單起見,我們采用類似于中心化拓?fù)浣Y(jié)構(gòu)的P2P模式,所有客戶都需要與中心服務(wù)器相連,并將自己的網(wǎng)絡(luò)地址寫入服務(wù)器中,服務(wù)器只需要監(jiān)聽和更新用戶列表信息,并發(fā)送給客戶最新的用戶列表信息即可。當(dāng)需要點對點聊天時,客戶端只需要從本地用戶列表中讀取目標(biāo)用戶的網(wǎng)絡(luò)地址,并連接目標(biāo)用戶,即可實現(xiàn)通信。因為是P2P系統(tǒng),客戶端要同時扮演服務(wù)器和客戶端兩個角色,所以,用戶登錄后都會創(chuàng)建一個接收其他用戶連接的監(jiān)聽線程,以實現(xiàn)服務(wù)器的功能。2)確定P2P模式基于P2P范型的即時聊天系統(tǒng)開發(fā)創(chuàng)建Socket、綁定地址和端口號,監(jiān)聽并接受客戶端的連接請求。服務(wù)器端在客戶連接后自動獲取客戶端用戶名、IP地址和端口號,并將其保存在服務(wù)器端的用戶列表中,同時更新所有在線用戶的客戶端在線用戶列表信息,以方便客戶了解上下線的實時情況,以進(jìn)行聊天。當(dāng)有用戶下線時,服務(wù)器端要能即時監(jiān)聽到,并更新用戶列表信息,發(fā)送給所有在線客戶端。對在線用戶數(shù)量進(jìn)行統(tǒng)計。3)確定服務(wù)器主要任務(wù)基于P2P范型的即時聊天系統(tǒng)開發(fā)客戶端創(chuàng)建Socket,并調(diào)用connect()函數(shù),向中心服務(wù)器發(fā)送連接請求??蛻舳嗽诘卿浐笠脖仨毘洚?dāng)服務(wù)器,以接收其他用戶的連接請求,所有需要創(chuàng)建一個用戶接收線程來監(jiān)聽。用戶登錄后需要接收來自服務(wù)器的所有在線用戶信息列表,并更新本地的用戶列表信息,以方便選擇特定用戶進(jìn)行聊天??蛻舳丝梢允褂萌喊l(fā)功能,向在線用戶列表中的所有用戶發(fā)送聊天信息。4)確定客戶端主要任務(wù)基于P2P范型的即時聊天系統(tǒng)開發(fā)服務(wù)器主要任務(wù)客戶端主要任務(wù)創(chuàng)建Socket、綁定地址和端口號,監(jiān)聽并接受客戶端的連接請求自動獲取客戶端用戶名、IP地址和端口號,并將其保存在服務(wù)器端的用戶列表中,同時更新所有在線用戶的客戶端在線用戶列表信息當(dāng)有用戶下線時,服務(wù)器端要能即時監(jiān)聽到,并更新用戶列表信息,發(fā)送給所有在線客戶端。對在線用戶數(shù)量進(jìn)行統(tǒng)計。創(chuàng)建Socket,并調(diào)用connect()函數(shù),向中心服務(wù)器發(fā)送連接請求。在登錄后也必須充當(dāng)服務(wù)器,接收其他用戶的連接請求,需要創(chuàng)建一個用戶接收線程來監(jiān)聽用戶登錄后需要接收來自服務(wù)器的所有在線用戶信息列表,并更新本地的用戶列表信息客戶端可以使用群發(fā)功能,向在線用戶列表中的所有用戶發(fā)送聊天信息注意,服務(wù)器向所有客戶發(fā)送最新用戶列表信息,及客戶端的群發(fā)功能,都是通過簡單地遍歷用戶列表來實現(xiàn)?;赑2P范型的即時聊天系統(tǒng)開發(fā)中心服務(wù)器啟動后會自動創(chuàng)建一個監(jiān)聽線程,以接受客戶端發(fā)來的連接請求。當(dāng)客戶端與服務(wù)器連接后,客戶端會將自己的信息(用戶名、IP地址和端口號等)寫入socket,服務(wù)器端從此socket中讀取該用戶信息,并登記到用戶信息列表中。然后,服務(wù)器將最新的用戶信息列表群發(fā)給所有在線的客戶端,以便客戶端得到最新的用戶列表。步驟1、2展示了客戶登陸服務(wù)器的過程。5)確定交互過程:登陸基于P2P范型的即時聊天系統(tǒng)開發(fā)每個連接到中心服務(wù)器的客戶都會得到最新的用戶信息列表。如步驟3所示,若Client2欲與Client3聊天,則Client2檢索自己的用戶信息列表,得到Client3的用戶信息后,便可與Client3進(jìn)行連接,實現(xiàn)通信。此過程,并不需要中心服務(wù)器的干預(yù)。5)確定交互過程:通信基于P2P范型的即時聊天系統(tǒng)開發(fā)當(dāng)有一個客戶需要下線時,例如圖中的Client1,那么Client1首先將下線請求寫入socket,中心服務(wù)器接收到含有下線請求標(biāo)記的信息后,Client1便通過握手機(jī)制下線(為了安全關(guān)閉socket)。Client1安全下線后,中心服務(wù)器會將Client1的用戶信息從在線列表中刪除,并將更新后的用戶列表、下線用戶名稱和當(dāng)前網(wǎng)絡(luò)的在線用戶情況等群發(fā)給所有在線客戶端,以便客戶端得到最新的在線用戶列表。5)確定交互過程:登出基于P2P范型的即時聊天系統(tǒng)開發(fā)客戶端的群發(fā)功能與服務(wù)器端的群發(fā)類似,都采用遍歷用戶列表的方法。例如,圖中Client3欲與所有在線用戶聊天,則只要遍歷Client3的在線用戶列表,與所有在線用戶進(jìn)行連接,便可以進(jìn)行群聊。5)確定交互過程:群聊基于P2P范型的即時聊天系統(tǒng)開

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論