熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

JXTA Platform JAVA參考實現源代碼分析(2)

2013-11-23 19:45:01  來源: Java高級技術 

   引言
  管道的概念源於Unix是不同線程之間直接傳輸數據的基本手段JDK中javaio包中就有管道類同時管道在JXTA中是最基本的概念是對等點之間的數據傳輸的主要方式對等管道協議(PBP)明確規范了對等管道的綁定解析響應
  
  本文依次剖析集中式(JDK)和對等環境下(JXTA)管道的實現方式對比分析其異同然後嘗試在JXTA中建立一個虛擬的全雙工的管道
  
  本文的目標是通過對不同環境下管道的實現方式對比分析來理解為什麼JXTA采用管道作為基本的數據傳輸手段
  
   管道的形象化描述
  一個生活中的情景現在有兩個地區ABA是石油生產區B是石油消費區現在B地區需要消費A地區的石油當然可以通過海運空運獲得然而最通常的方式是架設輸油管道如圖所示
  
 

  
   引言
  管道的概念源於Unix是不同線程之間直接傳輸數據的基本手段JDK中javaio包中就有管道類同時管道在JXTA中是最基本的概念是對等點之間的數據傳輸的主要方式對等管道協議(PBP)明確規范了對等管道的綁定解析響應
  
  本文依次剖析集中式(JDK)和對等環境下(JXTA)管道的實現方式對比分析其異同然後嘗試在JXTA中建立一個虛擬的全雙工的管道
  
  本文的目標是通過對不同環境下管道的實現方式對比分析來理解為什麼JXTA采用管道作為基本的數據傳輸手段
  
   管道的形象化描述
  一個生活中的情景現在有兩個地區ABA是石油生產區B是石油消費區現在B地區需要消費A地區的石油當然可以通過海運空運獲得然而最通常的方式是架設輸油管道如圖所示
  
  java中流的概念和管道的概念都可以通過此案例闡述A與B之間連接的就是管道負責將A的石油向B輸出A向管道輸出數據(output)B從管道輸入數據(input)可以這樣理解管道是A的輸出對象是B的數據源這裡就產生了三個類輸出流A輸入流B管道輸入流B負責如何獲取數據(read 操作)輸出流A負責如何消費數據(write操作)管道負責連接它們(connect 操作)其實在實現時管道類分解為管道口管道出口由入口出口負責連接在復雜的網絡環境中這種連接方式可以有專門的網絡協議負責(例如JXTA中的PBP全稱Pipe Bind Protocol)
  
  由以上描述我們可以清楚知道最原始的管道就是單向的文章後面介紹的雙向管道是用兩個單向管道虛擬的而非真實的連接方式不難發現管道最關鍵的問題是如何協調輸出(A)與輸入(B)這在不同的網絡環境會遇到不同的問題最簡單的是同一JVM下的不同過程(線程或任務)之間用同步方式傳遞數據而對等環境下如何去發現對方就是一個很現實的問題這僅僅只是問題的其中之一下面的章節會依次分析
  
   集中式環境下管道的實現
  問題的描述A與B是在同一JVM中AB有一方能夠發現另一方的存在A將數據發往B方A發送數據與B接收數據是相互獨立的
  
  現在回到問題的最初為什麼要使用管道?A只管發送B只管接受那麼數據在哪兒呢?經過下面的分析就會明白管道把管理數據緩沖區的重任交給了他自己AB均是圍繞這個緩沖區來啟停線程的顯然這才是問題的本質
  
  JDK中類PipeInputStream(即前面所述的B)與PipeOutputStream(即前面所述的的A)可以很好的解決這一問題首先給出類圖如下
  
 

  下面是將類PipeOutputStream的connect方法代碼簡化後給予注釋
  
  public synchronized void connect(PipedInputStream snk) throws IOException {
   sink = snk; //將PipeInputStream的實例作為PipeOutputStream的一個屬性以便調用
   snkin = ;//緩沖區的輸入位置<表示緩沖區為空
   snkout = ;//緩沖區的輸出位置
  nnected = true;
  }
  
  連接以後PipeOutputStream的write操作直接調用sinkreceive(b);這樣對緩沖區buffer的維護就變成了read()和receive()操作之間的線程同步JDK對緩沖區的處理非常巧妙采用了循環列表它用緩沖區的標志位的變化來代替數據的移動類似於生活中的時鐘把線性的時間規范為小時來表示這不屬於本文的論述范圍就不繼續分析了
  
  read操作正常情況下從out位置讀取數據緩沖區空時進入等待狀態以輪詢的方式(秒間隔)來自我釋放
  
  receive操作正常情況下向in位置寫入數據緩沖區滿時進入等待狀態同樣以輪詢的方式(秒間隔)來自我釋放
  
   JXTA對等管道的實現
  通過對JDK的分析我們可以了解到在集中式環境下管道的架設方案是比較簡單的在對等環境下(分布式環境下也類似)出於同樣的目標遇到的問題卻在急劇的擴大例如管道入口和出口之間如何相互發現?數據如何保證在不同的環境下傳送?甚至對管道本身的概念發生質疑一定是單入口單出口嗎?
  
  JXTA規范中管道是在端點之上的服務或應用之間發送和接收信息的虛擬連接通道管道提供在對等端點傳輸之上的網絡抽象管道有點到點和廣播兩種通信模式
  
  JXTA是通過管道廣告來唯一標示管道的輸出管道要找到與其廣告相同的輸入管道才能發送數據廣告內容如下
  
  <!DOCTYPE jxta:PipeAdvertisement>
  <jxta:PipeAdvertisement xmlns:jxta=;>
   <Id>
  urn:jxta:uuidAEAEABBEEFCBE
   </Id>
   <Type>
   JxtaUnicast
   </Type>
   <Name>
   PipeExample
   </Name>
  </jxta:PipeAdvertisement>
  
  如果您需要對JXTA管道有實例化的概念請參考Sing Li的使pp能進行交互操作Jxta命令shell 這篇文章有部分內容專門介紹了如何在通過shell使用管道本文主要是從編程的視角去看管道是如何實現的
  
   客戶視角
  
  Project JXTA : Java Programmers Guide Chapter有個例子闡述如何去在對等點之間發送信息讀者可以到下載源碼現在從客戶視角簡要的分析它的傳送原理要深入的了解可以看下一節的系統視角分析
  
  該例中有兩個對等點並且構建了兩個不同的類一個負責接收(Pipelistener)一個負責發送(PipeExample)具體的接收次序可以參考時序圖
  
 educitycn/img_///gif>

  類Pipelistener實現了接口PipeMsgListener類PipeExample實現了接口OutputPipeListener
  
  由時序圖(這是兩個JVM中的類所以時序符號是獨立標示的)可以清晰的獲知各個對等點的前步是相互獨立的各自的第采用回調的方式建立輸入和輸出管道一旦對等系統探測到對方的存在就分別觸發各自的事件發送或接收消息顯然JXTA中管道是異步的
  
  調試該例程時注意先建立輸入管道然後建立輸出管道因為輸出管道在一定的時間和次數內探測不到輸入管道的存在就會主動放棄否則容易讓網絡系統在這些無休止的探測中癱瘓
  
   系統視角
  
  從上面的例程中可以了解對等管道的創建方法以及數據流程但是不能明確對等系統是如何去實現的JXTA中管道的實現比在JDK中實現要復雜得多具體的技術標准可以參考對等管道綁定協議(PBP)此協議規范了JXTA中管道的概念但並沒有涉及到如何去實現這同樣是所有JXTA協議的特征它們的目標是闡述what it is而把how to do it留給開發者這樣有利於增強系統的開放性其中Java參考實現就是該協議實現的一個案例以下將具體分析
  
  首先看管道實現的類圖(以單播為例)
  
 educitycn/img_///gif>

  關鍵的類
  
   InputPipeImpl 輸入管道的實現類
   NonBlockingOutputPipe 輸出管道的實現類
   PipeServiceImpl 管道服務的實現類負責創建輸入輸出管道
   PipeResolver 提供管道綁定的解析服務
   
  通過客戶視角的分析可以得知系統外部是通過PipeServiceImpl來獲取輸入輸出管道那麼消息是如何在對等系統中通過管道過濾和傳遞的? 從程序實現的角度涉及到太多的技術細節JXTA的參考實現中有著龐雜的監聽系統本文嘗試用一個案例從兩個層次去解析這個問題兩個層次分別是消息的具體形式服務和端點協議的具體分發策略很顯然這裡我們把注意力放在了管道的架構路徑上而把如何去架構放在了一邊我想它們是有先後關系的並且距離並不遙遠
  
   案例描述
  現在假設有兩個對等點alas 和sisal 在一個局域網內按照客戶視角那一節的例程sisal先建立輸入管道alas建立輸出管道由於同一網內可以用廣播的方式發送查詢信息可以不設rendevous並且路由是兩點間的消息傳遞過程得到了一定的簡化
  
   案例分析
  以上案例中從輸入輸出管道的建立到完成對接並傳輸數據總共有個步驟
  
  sisal建立輸入管道
  alasl建立輸出管道需要查找輸入管道通過廣播向網絡發出管道查詢消息
  sisal獲得alas的管道查詢消息通過單播向sisal發出響應表示
  alas獲得sisal的響應通過單播向alas發出數據
  sisal獲得數據
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27397.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.