国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

JXTA Platform JAVA參考實(shí)現(xiàn)源代碼分析(2)

2019-11-18 12:18:27
字體:
供稿:網(wǎng)友

  1 引言
  管道的概念源于Unix,是不同線程之間直接傳輸數(shù)據(jù)的基本手段。JDK中java.io包中就有管道類,同時(shí),管道在JXTA中是最基本的概念,是對等點(diǎn)之間的數(shù)據(jù)傳輸?shù)闹饕绞健Φ裙艿绤f(xié)議(PBP)明確規(guī)范了對等管道的綁定,解析,響應(yīng)。
  
  本文依次剖析集中式(JDK)和對等環(huán)境下(JXTA)管道的實(shí)現(xiàn)方式,對比分析其異同,然后嘗試在JXTA中建立一個(gè)虛擬的全雙工的管道。
  
  本文的目標(biāo)是通過對不同環(huán)境下管道的實(shí)現(xiàn)方式對比分析,來理解為什么JXTA采用管道作為基本的數(shù)據(jù)傳輸手段。
  
  2 管道的形象化描述
  一個(gè)生活中的情景:現(xiàn)在有兩個(gè)地區(qū)A,B。A是石油生產(chǎn)區(qū),B是石油消費(fèi)區(qū),現(xiàn)在B地區(qū)需要消費(fèi)A地區(qū)的石油,當(dāng)然可以通過海運(yùn),空運(yùn)獲得,然而最通常的方式是架設(shè)輸油管道。如圖所示:
  
 JXTA Platform JAVA參考實(shí)現(xiàn)源代碼分析(2)(圖一)

  
  1 引言
  管道的概念源于Unix,是不同線程之間直接傳輸數(shù)據(jù)的基本手段。JDK中java.io包中就有管道類,同時(shí),管道在JXTA中是最基本的概念,是對等點(diǎn)之間的數(shù)據(jù)傳輸?shù)闹饕绞健Φ裙艿绤f(xié)議(PBP)明確規(guī)范了對等管道的綁定,解析,響應(yīng)。
  
  本文依次剖析集中式(JDK)和對等環(huán)境下(JXTA)管道的實(shí)現(xiàn)方式,對比分析其異同,然后嘗試在JXTA中建立一個(gè)虛擬的全雙工的管道。
  
  本文的目標(biāo)是通過對不同環(huán)境下管道的實(shí)現(xiàn)方式對比分析,來理解為什么JXTA采用管道作為基本的數(shù)據(jù)傳輸手段。
  
  2 管道的形象化描述
  一個(gè)生活中的情景:現(xiàn)在有兩個(gè)地區(qū)A,B。A是石油生產(chǎn)區(qū),B是石油消費(fèi)區(qū),現(xiàn)在B地區(qū)需要消費(fèi)A地區(qū)的石油,當(dāng)然可以通過海運(yùn),空運(yùn)獲得,然而最通常的方式是架設(shè)輸油管道。如圖所示:
  
  java中流的概念和管道的概念都可以通過此案例闡述,A與B之間連接的就是管道,負(fù)責(zé)將A的石油向B輸出。A向管道輸出數(shù)據(jù)(output),B從管道輸入數(shù)據(jù)(input),可以這樣理解,管道是A的輸出對象,是B的數(shù)據(jù)源。這里就產(chǎn)生了三個(gè)類:輸出流A,輸入流B,管道。輸入流B負(fù)責(zé)如何獲取數(shù)據(jù)(read 操作),輸出流A負(fù)責(zé)如何消費(fèi)數(shù)據(jù)(write操作),管道負(fù)責(zé)連接它們(connect 操作)。其實(shí),在實(shí)現(xiàn)時(shí),管道類分解為管道口,管道出口,由入口出口負(fù)責(zé)連接。在復(fù)雜的網(wǎng)絡(luò)環(huán)境中,這種連接方式可以有專門的網(wǎng)絡(luò)協(xié)議負(fù)責(zé)(例如,JXTA中的PBP,全稱Pipe Bind PRotocol)。
  
  由以上描述,我們可以清楚知道最原始的管道就是單向的,文章后面介紹的雙向管道,是用兩個(gè)單向管道虛擬的,而非真實(shí)的連接方式。不難發(fā)現(xiàn)管道最要害的問題是如何協(xié)調(diào)輸出(A)與輸入(B)。這在不同的網(wǎng)絡(luò)環(huán)境會碰到不同的問題,最簡單的是同一JVM下的不同過程(線程或任務(wù))之間用同步方式傳遞數(shù)據(jù)。而對等環(huán)境下,如何去發(fā)現(xiàn)對方就是一個(gè)很現(xiàn)實(shí)的問題,這僅僅只是問題的其中之一,下面的章節(jié)會依次分析。
  
  3 集中式環(huán)境下管道的實(shí)現(xiàn)
  問題的描述:A與B是在同一JVM中,A,B有一方能夠發(fā)現(xiàn)另一方的存在,A將數(shù)據(jù)發(fā)往B方,A發(fā)送數(shù)據(jù)與B接收數(shù)據(jù)是相互獨(dú)立的。
  
  現(xiàn)在回到問題的最初:為什么要使用管道?A只管發(fā)送,B只管接受,那么數(shù)據(jù)在哪兒呢?經(jīng)過下面的分析,就會明白管道把治理數(shù)據(jù)緩沖區(qū)的重任交給了他自己,A,B均是圍繞這個(gè)緩沖區(qū)來啟停線程的,顯然這才是問題的本質(zhì)。
  
  JDK中,類PipeInputStream(即前面所述的B)與PipeOutputStream(即前面所述的的A)可以很好的解決這一問題。首先給出類圖如下。
  
 JXTA Platform JAVA參考實(shí)現(xiàn)源代碼分析(2)(圖二)

  下面是將類PipeOutputStream的connect方法代碼簡化后給予注釋。
  
  public synchronized void connect(PipedInputStream snk) throws IOException {
   sink = snk; //將PipeInputStream的實(shí)例作為PipeOutputStream的一個(gè)屬性,以便調(diào)用
   snk.in = -1;//緩沖區(qū)的輸入位置,<0表示緩沖區(qū)為空
   snk.out = 0;//緩沖區(qū)的輸出位置
  snk.connected = true;
  }
  
  連接以后,PipeOutputStream的write操作直接調(diào)用sink.receive(b);這樣,對緩沖區(qū)buffer的維護(hù),就變成了read()和receive()操作之間的線程同步。JDK對緩沖區(qū)的處理非常巧妙,采用了循環(huán)列表,它用緩沖區(qū)的標(biāo)志位的變化來代替數(shù)據(jù)的移動,類似于生活中的時(shí)鐘把線性的時(shí)間規(guī)范為24小時(shí)來表示。這不屬于本文的論述范圍,就不繼續(xù)分析了。
  
  read操作,正常情況下,從out位置讀取數(shù)據(jù)。緩沖區(qū)空時(shí)進(jìn)入等待狀態(tài)。以輪詢的方式(1秒間隔)來自我釋放。
  
  receive操作,正常情況下,向in位置寫入數(shù)據(jù)。緩沖區(qū)滿時(shí)進(jìn)入等待狀態(tài)。同樣,以輪詢的方式(1秒間隔)來自我釋放。
  
  4 JXTA對等管道的實(shí)現(xiàn)
  通過對JDK的分析,我們可以了解到在集中式環(huán)境下,管道的架設(shè)方案是比較簡單的。在對等環(huán)境下(分布式環(huán)境下也類似),出于同樣的目標(biāo),碰到的問題卻在急劇的擴(kuò)大。例如,管道入口和出口之間如何相互發(fā)現(xiàn)?數(shù)據(jù)如何保證在不同的環(huán)境下傳送?甚至,對管道本身的概念發(fā)生質(zhì)疑:一定是單入口,單出口嗎?
  
  JXTA規(guī)范中,管道是在端點(diǎn)之上的服務(wù)或應(yīng)用之間發(fā)送和接收信息的虛擬連接通道,管道提供在對等端點(diǎn)傳輸之上的網(wǎng)絡(luò)抽象。管道有點(diǎn)到點(diǎn)和廣播兩種通信模式。
  
  JXTA是通過管道廣告來唯一標(biāo)示管道的,輸出管道要找到與其廣告相同的輸入管道才能發(fā)送數(shù)據(jù),廣告內(nèi)容如下
  
  <!DOCTYPE jxta:PipeAdvertisement>
  <jxta:PipeAdvertisement XMLns:jxta="http://jxta.org";>
   <Id>
  urn:jxta:uuid-59616261646162614A787461503250335003093E73074218AE3ABBE08EF3CBE303
   </Id>
   <Type>
   JxtaUnicast
   </Type>
   <Name>
   PipeExample
   </Name>
  </jxta:PipeAdvertisement>
  
  假如您需要對JXTA管道有實(shí)例化的概念,請參考Sing Li的使p2p能進(jìn)行交互操作:Jxta命令shell ,這篇文章有部分內(nèi)容專門介紹了如何在通過shell使用管道。本文主要是從編程的視角去看管道是如何實(shí)現(xiàn)的。
  
  4.1 客戶視角
  
  Project JXTA : Java Programmer's Guide Chapter7有個(gè)例子闡述如何去在對等點(diǎn)之間發(fā)送信息,讀者可以到www.jxta.org下載源碼。現(xiàn)在從客戶視角簡要的分析它的傳送原理,要深入的了解可以看下一節(jié)的系統(tǒng)視角分析。
  
  該例中,有兩個(gè)對等點(diǎn),并且構(gòu)建了兩個(gè)不同的類:一個(gè)負(fù)責(zé)接收(Pipelistener),一個(gè)負(fù)責(zé)發(fā)送(PipeExample)。具體的接收次序可以參考時(shí)序圖:
  
 JXTA Platform JAVA參考實(shí)現(xiàn)源代碼分析(2)(圖三)

  類Pipelistener實(shí)現(xiàn)了接口PipeMsgListener,類PipeExample實(shí)現(xiàn)了接口OutputPipeListener。
  
  由時(shí)序圖(這是兩個(gè)JVM中的類,所以時(shí)序符號是獨(dú)立標(biāo)示的)可以清楚的獲知,各個(gè)對等點(diǎn)的前1,2步是相互獨(dú)立的。各自的第3步,采用回調(diào)的方式建立輸入和輸出管道。一旦對等系統(tǒng)探測到對方的存在,就分別觸發(fā)各自的事件發(fā)送或接收消息。顯然JXTA中管道是異步的。
  
  調(diào)試該例程時(shí),注重先建立輸入管道,然后建立輸出管道。因?yàn)椋敵龉艿涝谝欢ǖ臅r(shí)間和次數(shù)內(nèi)探測不到輸入管道的存在,就會主動放棄。否則,輕易讓網(wǎng)絡(luò)系統(tǒng)在這些無休止的探測中癱瘓。
  
  4.2 系統(tǒng)視角
  
  從上面的例程中,可以了解對等管道的創(chuàng)建方法,以及數(shù)據(jù)流程,但是不能明確對等系統(tǒng)是如何去實(shí)現(xiàn)的。JXTA中管道的實(shí)現(xiàn)比在JDK中實(shí)現(xiàn)要復(fù)雜得多,具體的技術(shù)標(biāo)準(zhǔn)可以參考對等管道綁定協(xié)議(PBP),此協(xié)議規(guī)范了JXTA中管道的概念,但并沒有涉及到如何去實(shí)現(xiàn),這同樣是所有JXTA協(xié)議的特征。它們的目標(biāo)是闡述what it is,而把how to do it留給開發(fā)者,這樣有利于增強(qiáng)系統(tǒng)的開放性。其中Java參考實(shí)現(xiàn),就是該協(xié)議實(shí)現(xiàn)的一個(gè)案例,以下將具體分析。
  
  首先看管道實(shí)現(xiàn)的類圖(以單播為例):
  
 JXTA Platform JAVA參考實(shí)現(xiàn)源代碼分析(2)(圖四)

  要害的類:
  
   InputPipeImpl :輸入管道的實(shí)現(xiàn)類
   NonBlockingOutputPipe :輸出管道的實(shí)現(xiàn)類
   PipeServiceImpl :管道服務(wù)的實(shí)現(xiàn)類,負(fù)責(zé)創(chuàng)建輸入輸出管道
   PipeResolver :提供管道綁定的解析服務(wù)
   
  通過客戶視角的分析,可以得知系統(tǒng)外部是通過PipeServiceImpl來獲取輸入輸出管道。那么消息是如何在對等系統(tǒng)中通過管道過濾和傳遞的? 從程序?qū)崿F(xiàn)的角度,涉及到太多的技術(shù)細(xì)節(jié),JXTA的參考實(shí)現(xiàn)中有著龐雜的監(jiān)聽系統(tǒng)。本文嘗試用一個(gè)案例從兩個(gè)層次去解析這個(gè)問題,兩個(gè)層次分別是消息的具體形式,服務(wù)和端點(diǎn)協(xié)議的具體分發(fā)策略。很顯然,這里我們把注重力放在了管道的架構(gòu)路徑上,而把如何去架構(gòu)放在了一邊,我想它們是有先后關(guān)系的,并且距離并不遙遠(yuǎn)。
  
  5 案例描述
  現(xiàn)在假設(shè)有兩個(gè)對等點(diǎn)alas 和sisal ,在一個(gè)局域網(wǎng)內(nèi),按照客戶視角那一節(jié)的例程sisal先建立輸入管道,alas建立輸出管道。由于同一網(wǎng)內(nèi)可以用廣播的方式發(fā)送查詢信息,可以不設(shè)rendevous,并且路由是兩點(diǎn)間的,消息傳遞過程得到了一定的簡化。
  
  6 案例分析
  以上案例中,從輸入輸出管道的建立到完成對接并傳輸數(shù)據(jù)總共有5個(gè)步驟:
  
  sisal建立輸入管道
  alasl建立輸出管道,需要查找輸入管道,通過廣播向網(wǎng)絡(luò)發(fā)出管道查詢消息
  sisal獲得alas的管道查詢消息,通過單播向sisal發(fā)出響應(yīng)表示
  alas獲得sisal的響應(yīng),通過單播向alas發(fā)出數(shù)據(jù)
  sisal獲得數(shù)據(jù)
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 天长市| 香港 | 尉犁县| 梁河县| 漳平市| 宁晋县| 利津县| 商洛市| 乌拉特后旗| 屏东县| 沙雅县| 延边| 康保县| 乐平市| 金乡县| 鄂温| 固原市| 邛崃市| 米泉市| 漠河县| 铜川市| 望谟县| 秀山| 澄城县| 秦安县| 什邡市| 塔城市| 海门市| 龙里县| 施甸县| 澳门| 钟祥市| 深水埗区| 垣曲县| 阿拉善右旗| 萨嘎县| 河曲县| 泊头市| 敦化市| 余干县| 长治县|