麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

使P2P能進行交互操作:Jxta命令shell

2019-11-18 14:25:30
字體:
來源:轉載
供稿:網友

  學習從頭開始構建 P2P 應用
Sing Li ([email protected])
作家,Wrox 出版社

Jxta 工程按社區方式運作,旨在為對等應用構建實用應用程序底層。Jxta 最初的參考實現包含一個命令行 shell,使您無須編程就能試驗核心 Jxta 平臺。在本系列(共 3 部分)的第 2 部分,Sing Li 將帶我們去實際體驗一下 Jxta shell。您將?索它的命令集并用 java 編程語言編寫您自己的定制命令來擴展它的功能。請在討論論壇與作者和其他讀者共享您關于本文的心得。
Jxta 命令 shell 正是多數 Jxta 開發者將碰到的第一個 Jxta 應用。事實上,Jxta 開發包(Jxta development kit)把 shell 作為缺省應用包含在其中。這樣做有一個很好的理由:一行代碼都不用寫,通過 shell 您就可以體會組成 Jxta 平臺的組件。與大家熟悉的 UNIX 或 DOS shell 一樣,shell 也是一個大量使用環境變量的命令行工具。在本系列的這一部分中,您將熟悉這個萬能 shell 的基本命令,并學習如何編寫您自己的命令來增強它的功能。

在我們開始之前,您必須先安裝 Jxta shell。您可以從本文末尾的參考資料部分中下載 Jxta shell 分發包(請選擇一個穩定版本)。

安裝 Jxta shell

在您的機器上安裝 Jxta,至少到 29i 版(正在編寫的當前版本)為止,在多數家用和辦公系統上是很不輕易的。主要的困難是源于 Jxta 與防火墻代理和事實上標準的家用網絡 NAT 路由器之間的工作方式。

要在因特網之外與其它對等節點進行交互,您必須根據 Jxta 安裝文檔進行具體配置。然而,就本文來說,我們無須連接到我們的本地網之外,就可以試驗 Jxta。只要安裝該分發包并執行本文的指導就行了。在本系列的下一篇即最后一篇論文中,我們將討論如何為因特網配置我們的 Jxta 系統。

安裝 Jxta
請按照下列步驟安裝進行本文試驗所需的環境:

下載本文的分發源代碼并將它解壓到您選定的目錄。在本文所有地方,我們都將稱這個目錄為 CODEROOT。


解壓縮 Jxta shell 的二進制分發文件(jxtashell.zip)到同一個 CODEROOT 目錄。


檢查 CODEROOT 下的 lib 目錄,確保其中已經包含 jxta.jar 和 jxtashell.jar。


進入 CODEROOT 下的 shell 目錄并運行 runshell.bat 文件(包含在本文的分發代碼中)。這將啟動圖 1 所示的 GUI 配置實用程序。


請在 GUI 配置實用程序的 peer name(對等機名)處輸入 node1。確保選上 TCP 傳輸部分而且您所輸入的主機名或 IP 地址須是機器的有效本地地址。同時確保您已經把本節點的 TCP 端口號指定為 9700。所有這些都顯示在如下的圖 1 中。


禁用 HTTP 傳輸,為此請不復選相應的復選框。HTTP 傳輸用于與防火墻之外的對等機進行通信(通過集中服務(rendezvous service));我們不需要它。


單擊 OK 按鈕啟動 Jxta shell 的一個實例。
圖 1. Jxta GUI 配置實用程序


剖析對等機
是進行一些試驗的時候了。跟 UNIX shell 中的情形一樣,Jxta shell 的命令也與環境變量交互。要找出對等機的更多信息,試一下以下命令:


JXTA>whoami




您的輸出將是一個語法上類似于 xml 的結構化文檔。


<Peer>node1</Peer>
<KeyWords>Netpeer group by default</Keywords>
<PeerId>
jxta://59616261646162614A78746150325033DB1EB6636DCE4B2990CA888B36CD96C7000
0000000000000000000000000000000000000000000000000000000000301
</PeerId>
<TransportAddress>tcp://169.254.101.152:9700/</TransportAddress>



這里,我們可以看到本地對等機名 node1 與一個很長的對等機 ID(包在 <PeerId> 元素中)相對應。請注重我們已經在一個名稱為 Netpeer 的缺省對等組中。通達本對等機的傳輸地址包在 <TransportAddress> 元素中。假如我們沒有特地修改過 shell 配置,那么 shell 引導機制將把我們放到缺省對等組中。事實上,我們可以通過以下命令更多地了解這個缺省組:


JXTA>whoami -g




這個 whoami 命令的變體,使用 -g 開關,將檢查我們當前是其中成員的組并將獲得更多該組的信息。我們的輸出看起來可能像這樣:


<peer group>Netpeer group</peer group>
<Keywords>Netpeer group by default</Keywords>
<peer groupId>
jxta://59616261646162614A757874614D504700000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000201
</peer groupId>
<Service>jxta.service.discovery</Service>
<Service>jxta.service.pipe</Service>
<Service>jxta.service.resolver</Service>
<Service>jxta.service.rendezvous</Service>
<Service>jxta.service.peerinfo</Service>
<Service>jxta.service.membership</Service>




這就是缺省 Netpeer 組。請注重表中列出的所有可用核心對等組服務;每個服務都被包在 <Service> 標記中。

P2P 基礎通信
在對等機開機、運行并且是 Netpeer 組的成員的情況下,我們現在可以嘗試進行一些 P2P Jxta 通信。我們將:

創建一個管道
創建一條消息
通過管道把消息發送到另一個對等機
為使用 Jxta shell 上可用的命令,我們須將上述任務分解為如下步驟:

創建一條管道廣告。
創建一條基于該廣告的管道。
啟動一個新的 shell 實例。
在新 shell 上,創建一條基于該廣告的輸出管道。
在新 shell 上,創建一條消息。
在新 shell 上,附加一個文件到該消息上。
阻塞老 shell,等待來自輸入管道的消息。
在新 shell 上,發送該消息。
現在,讓我們一步一步地完成這個過程,并分析我們將用到的所有 shell 命令。我們將在這個過程中熟悉幾乎所有當前可用的 shell 命令。

創建一條管道廣告
我們可以用如下的 shell 命令創建一條管道廣告并將它指定給名為 dwAdv 的環境變量:


JXTA>dwAdv = mkadv -p




mkadv 命令用于為對等組或管道創建廣告。(在這個案例中,-p 開關表示這是一條管道廣告。)在 Jxta 的當前發展階段上,-t 開關尚不能用,我們將用它來指定管道類型。最終您將可以用這個命令創建不同類型的管道廣告(例如,廣播管道廣告,對等管道廣告,等等;請參閱本系列的第一部分獲取更多具體信息)。

我們可以用如下命令看到 mkadv 的效果:


JXTA>env




env 列出所有環境變量。您將看到環境變量 dwAdv 現在已經被設置:


dwAdv = PipeService Advertisement (class net.jxta.impl.PRotocol.PipeAdv)




創建一條基于該廣告的輸入管道
現在我們將創建一條與名為 dwinpipe 的環境變量聯系在一起的輸入管道:


JXTA>dwinpipe = mkpipe -i dwAdv




-i 開關表示輸入管道,dwAdv 則是我們前面創建的管道廣告。

用 env 命令將可以看到 dwinpipe 現在已經與該輸入管道聯系在一起:


dwinpipe = InputPipe of dwAdv (class net.jxta.impl.pipe.InputPipeImpl)




啟動一個新 shell
您可以用以下命令生成一個新的、帶有當前環境變量的 shell 實例:


JXTA>Shell -s




-s 開關在一個新窗口中創建一個新的、繼續老 shell 的所有環境變量的 shell。假如我們未使用 -s 開關,那么新 shell 的創建仍將繼續所有環境變量,但它將被“嵌套”或“堆”在同一個窗口中現有 shell 上。沒有新窗口會被顯示,并且您將不能訪問老 shell,直到您退出新 shell 為止。

在我們的示例中,請記住在兩個 shell 實例中我們將處理同一個對等機。在本文的后一部分中,我們將與多個對等機一起工作。

創建一條輸出管道
在新近創建的 shell 實例中,我們可以創建一個與 dwAdv 廣告聯系在一起的輸出管道。用到的命令是:


JXTA>dwoutpipe = mkpipe -o dwAdv




這條新的、可通過環境變量 dwoutpipe 訪問的管道將與我們前面創建的那條輸入管道聯系在一起,因為它們倆都基于同一條廣告(dwAdv)。假如要用這條管道來連接兩臺不同的對等機,我們就須為這條管道做廣告,這是我們將在以后討論的主題。

創建一條消息
我們現在要創建一條能通過該管道發送的消息。為此,我們首先創建一條與環境變量 dwMsg 聯系在一起的空消息。


JXTA>dwMsg = mkmsg




附加一個文件到該消息
導入名為 simple.txt 的文本文件(在 shell 目錄,它包含在參考資料中提供的源代碼中),并用如下命令把它與名為 dwData 的環境變量聯系起來:


JXTA>importfile -f simple.txt dwData




-f 開關是必須的。它表示緊接在后面的是一個文件名;這個用法跟 UNIX 的 tar 命令相似。省略它將導致未定義的行為,包括異常!

現在,將導入的文件作為一個標記值(與名為 dwTag 的標記聯系在一起)附加到消息上。從概念上說,我們是在把屬性附加到消息對象中。屬性將與消息一起通過管道傳送并可在另一端將它拆離。在下層,一個額外的 XML 片段被插入到結構化文檔(消息)中,它包含附加文檔,并以標記值命名;相關的報頭也被修改以反映新的、更大的大小。用 put 命令就可以完成這一切。稍后,可以用 get 命令從消息中抽取相同的標記值,get 命令通過逆向進行上述過程找回所導入的文件。

為把標記值作為一個屬性進行附加,我們用 put 命令:


JXTA>put dwMsg dwTag dwData




這個命令將通過 dwTag 把文本文件添加到消息正文中。

預備接收消息
在老的 shell 實例上,用以下命令開啟在輸入管道上阻塞著的接收:


JXTA>dwNewMsg = recv dwinpipe




這個命令將設置 shell 以等待消息并把環境變量 dwNewMsg 與任何通過管道收到的進入消息聯系起來。

通過管道發送該消息
回到新 shell 實例中,現在我們可以用這個命令通過管道發送帶有附加文件的消息:


JXTA>send dwoutpipe dwMsg




驗證消息和文件收據
在接收器處于阻塞狀態的老 shell 實例中,我們將看到:


JXTA>dwNewMsg = recv dwinpipe
recv has received a message




現在,試一下 env 并請注重環境變量 dwNewMsg 現在已經與接收到的消息聯系在一起。


dwNewMsg = Message from dwinpipe (class net.jxta.impl.endpoint.MessageImpl)




事實上,我們可以用 dwTag 標記輕易地從管道中抽取文件。用 get 命令使文件與環境變量 dwNewFile 聯系在一起:


JXTA>dwNewFile = get dwNewMsg dwTag




為查看傳輸文件的內容,我們可以使用如下命令:


JXTA>cat dwNewFile




文件內容將作為一個 XML 文檔顯示:


<?xml version="1.0"?>
<ShellDoc>
<Item>
This is a simple file for Jxta transfer. It can contain anything.
</Item>
</ShellDoc>




要把消息保存到名為 received.txt 的文件,請用這個命令:


JXTA>eXPortfile -f received.txt dwNewFile




這將把文件保存在 shell 最初從中啟動的目錄。-f 開關仍表示后面所跟的是一個文件名。

在兩個獨立的對等機之間建立管道
既然我們已經通過管道實際傳輸了一個文件,那就讓我們把 Jxta 系統的一些獨有特征重新整理一下:

管道用它的廣告唯一標識,廣告是嵌入在 XML 文檔中的一個標識符。


創建管道廣告的時候并沒有生成物理管道或連接;管道雖然存在但并未綁定到任何端點。


您可以在創建廣告之后的任何時候獨立地把輸入和輸出管道綁定到端點。


端點之間數據的實際傳輸通常由對等組內的下層管道服務協調。
我們上面的示例只使用一個對等機或端點。我們可以輕易地將它修改成能使用同一個缺省對等組內的兩臺對等機。為此,您可以按如下所述在同一臺機器上安裝 Jxta shell 的另一個對等機實例,或者也可以在同一個局域網的兩臺獨立機器上啟動 Jxta shell。

GUI 配置實用程序

GUI 配置實用程序只在您第一次啟動一個 shell 實例時出現。此后,配置信息被存儲在磁盤上并可被重用。這就是為什么我們要創建 shell 和 shell2 目錄的原因 ? 包含配置數據的兩套設置。假如您想再經歷一遍配置過程,您可以在下次啟動 shell 實例時,當您在 Jxta shell 中的時候輸入 peerconfig 命令來啟動 GUI 配置實用程序。

在同一臺機器上安裝兩臺獨立的對等機
為模擬有兩個節點的 P2P 網絡,我們將在我們安裝第一臺對等機的同一臺機器上安裝第二臺獨立的對等機。有了這個安裝,我們將不必在網絡的幾臺機器之間往返奔波就可以工作。順利進行這項工作的要害是把平臺上的各個實例設置成在不同的 TCP 端口上運行。為此,您可以采取這些步驟:

進入 CODEROOT 目錄下的 shell2 目錄。


運行 runshell.bat 文件啟動 shell。


這樣,Jxta GUI 配置實用程序將被啟動。把 TCP 端口改成 9701(回想一下,另一個 shell 實例,即對等機 node1 是在端口 9700),并輸入一個新的對等機名(本示例用的是 node2)。


禁用 HTTP 傳輸協議(不復選相應的框)并完成配置。
上述過程將啟動一臺獨立的對等機,這臺對等機雖然與 node1 在同一臺機器上運行,但 TCP 端口是不同的。現在我們可以創建管道并在兩臺獨立的對等機之間發送消息。從本質上說,我們可以把我們在前面的單個對等機的案例中所做的所有事情再做一遍 ? 但這次,我們將在新的對等機實例而不是第二個 shell 實例上做這些事情。

為方便起見,我們將把創建輸入管道實例的對等機用它的對等機名 ? node1 來稱呼它 ? 新的對等機實例則稱為 node2。在 node1 上創建了輸入管道之后,您必須使它的廣告對 node2 可見。在獨立的對等機之間,環境變量不自動共享;對同一臺機器上的獨立 shell 實例和連接在一個網絡上的不同機器上的對等機而言,情況也是如此。要在對等組內發布廣告,請使用 share 命令:


JXTA>share dwAdv




要在 node2 上查看廣告,您必須執行遠程 search:


JXTA>search -r




-r 開關表示該命令將搜索同一對等組內的遠程對等機所發布的廣告。記住,“遠程”對等機可以是運行在同一臺機器上的一個獨立的 shell 實例。

接著,再次輸入如下命令:


JXTA>search




這個動作將輪詢任何新近被發現的廣告。最后您將在 node2 上看到一些類似這樣的東西:


JXTA>search
JXTA Advertisement adv0




shell 將為每個被發現的廣告指定一個名為 advn 的環境變量,其中 n 從 0 開始。在我們的示例中,shell 把變量 adv0 指定給新近被發現的廣告。

現在您可以用 adv0 這個共享廣告來建立輸出管道:


JXTA>dwoutpipe = mkpipe -o adv0




上面討論了安裝兩臺對等機的必要步驟;剩下的全部步驟跟單個對等機的案例中的步驟一樣。用管道在一個對等組的對等機之間輕易地交換文件、數據和代碼是可能的。

擴展 shell:一個簡單示例
Jxta shell 被設計成用戶可以輕易地對它進行擴展的。這意味著您可以往 shell 添加定制命令。因為 Jxta shell 的參考實現是用 Java 語言實現的,所以動態類裝入意味著可以動態地添加 Jxta shell 擴展,而不用重新編譯 shell。這還意味著不同的用戶可以使用同一個基礎 shell 二進制文件,但卻保留他們自己喜歡的擴展設置。事實上,要編寫一個擴展,您甚至不必訪問 Jxta shell 的源代碼。說明這種令人驚異的可擴展性的最好辦法是舉一個小的例子。我們打算往 shell 添加一個名為 dwcmd(developerWorks command 的縮寫)的命令。執行 dwcmd 時只是打印一個文本字符串:


JXTA>dwcmd
This is a trivial Jxta shell extension.




這里是 dwcmd 擴展的源代碼(它很簡單):


package net.jxta.impl.shell.bin.dwcmd;
import net.jxta.impl.shell.*;
public class dwcmd extends ShellApp {
public dwcmd() {
}

public int startApp (String[] args) {
println ("This is a trivial Jxta shell extension.");
return ShellApp.appNoError;
}

public void stopApp () {
}

}




我們可以看到:

擴展繼續了 net.jxta.impl.shell.ShellApp 類。
它必須實現 StartApp() 和 stopApp() 方法。
它是 net.jxta.impl.shell.bin 包的一部分。
所有 shell 擴展都按照這種模式。當從 shell 命令行調用該命令時,StartApp() 方法被調用,而當退出 shell 時,StopApp() 方法被調用。

編譯并配置 shell 擴展
為成功編譯dwcmd.java 文件,當要調用編譯器時,我們必須把 jxtashell.jar 添加到 classpath 中。這一步使得 Java 編譯器對 Jxta 核心類和 shell 擴展代碼所使用的特定于 Jxta shell 的庫類都能進行處理。code 目錄已經提供了 makeit.bat 文件;文件內容如下:


set CODEROOT=..
javac -classpath
%CODEROOT%libjxta.jar;%CODEROOT%libjxtashell.jar
-d %CODEROOT%dwclasses netjxtaimplshellindwcmd*.java




請注重 dwcmd 命令是 net.jxta.impl.shell.bin 包的一部分。事實上,所有 shell 命令都是以這種方式配置的。這是 Jxta shell 找到命令的方式(使用內省)。這也正是在運行期間動態地把擴展添加到 shell 中,而不要求重新編譯 shell 本身的機制。

我們的 makeit.bat 編譯過程把輸出的類文件(classfiles)放在名為 dwclasses 的目錄中。我們必須把這個目錄添加到我們所運行的 shell 實例的 classpath 中。這在運行時把 shell 擴展類和 Jxta shell 實現類有效地合并在了一起。假如您看一下 shell 目錄中的 runshell.bat 文件,那么您將可以看到 classpath 中包含了它:


java -classpath
..libjxta.jar;..libjxtashell.jar;..liblog4j.jar;..dwclasses
net.jxta.impl.peergroup.Boot




這里,我們已經把 ..dwclasses 目錄添加到了運行 shell 的 VM 的 classpath 中。這把我們的 net.jxta.impl.shell.bin.dwcmd 包和 jxtashell.jar 中的其它 shell 命令有效地合并在了一起。圖 2 說明了這些命令合并的工作機制。

圖 2. 把定制命令 dwcmd 添加到 shell


現在假如您在 shell 目錄中啟動一個新的 shell 實例(用 runshell.bat),那么您將可以在該 shell 內訪問新的 dwcmd 命令。親自試試!

編寫一個復雜的 shell 擴展
既然我們已經熟悉創建 shell 擴展的基礎知識,那我們就能夠編寫一個更復雜的、實際能執行有用的 Jxta 工作的擴展。事實上,我們將創建一個能做以下工作的 shell 擴展:

創建一條管道廣告
創建一條基于該廣告的輸入管道
在組內共享該廣告
在輸入管道上等待消息
從消息中抽取所附加的文本文件
打印出該文本文件的內容
這與我們前面在 node1 上使用 shell 命令和 shell 變量時的順序是一樣的。現在,在擴展的幫助下,我們用一個定制命令就可以完成一切事情。

新的命令將被稱為 waitptext(wait pipe text 的縮寫)。您可以在子樹 net.jxta.impl.shell.bin(所有 shell 命令都必須位于此處)下找到它的源代碼。看看下面 waitptext.java 的導入清單以了解我們須導入的各個 Jxta 平臺包。


package net.jxta.impl.shell.bin.waitptext;
...
import net.jxta.pipe.*;
import net.jxta.endpoint.*;
import net.jxta.discovery.*;
import net.jxta.document.*;
import net.jxta.protocol.*;




這里是所包含的包及其功能的概略介紹:

包 用途
net.jxta.pipe 包含用于管道實現 InputPipe 和 Pipe 接口
net.jxta.endpoint 包含用于消息實現的 Message 接口
net.jxta.document 包含用于結構化文檔的一個類工廠(class factory)和一些接口,例如用在 Jxta 消息和廣告中的 XML 文檔(適用于 Jxta 的參考實現)
net.jxta.protocol 包含用于管道廣告實現的 PipeAdvertisement 接口;還包含一個用于創建新管道廣告的類工廠
net.jxta.protocol 包含使用 Jxta 協議的類和接口

在類 waitptext 中,我們定義了將要使用的 Jxta 對象類型(廣告、管道、消息和結構化文檔等等)的私有(private)實例。在命令行上,一切都被指定為 shell 變量;在 Jxta 中,我們必須更具體地說明類型。


public class waitptext extends ShellApp {

private PipeAdvertisement myPipeAdv = null;
private InputPipe myInpPipe = null;
private Message myMesg = null;
private InputStream myInpStream = null;
private StrUCturedDocument myStructDoc = null;
private Discovery myDiscovery = null;
private PeerGroup myGroup;




waitptext.java 中最重要的方法是 startApp(),命令的大部分工作都在這里完成。在這個案例中,我們把參數傳遞到命令中。這個參數是結構化文檔標記的名稱(在我們前面的示例中是 dwTag),它就是我們為拆離隨消息一起發送的文本文檔所要找的。我們判定用戶是否為消息標記名指定了參數;假如沒有,我們就使用缺省值(預先設置為 tmpTag):


private String tagName = "tmpTag";
public int startApp (String[] args) {
if (args.length != 0)
tagName = args[0];




創建一條管道廣告
我們用 AdvertisementFactory 靜態類來創建管道廣告,它是 net.jxta.document 包的一部分(因為廣告是一個結構化文檔)。您可以從本系列的第 1 部分中回想起每條廣告都有一個唯一的 ID;這里,我們通過創建一個新的 PipeID 實例來創建 ID。我們把當前組的 ID 作為參數傳進去以構造 PipeID,因為每個 PipeID 都包含它從中被創建的對等組的 ID。UUID 生成算法是內部平臺核心庫的一部分,并且新的 PipeID() 實現將在內部調用它。PipeID 實際上包含一個嵌入的組 ID,因為管道總是屬于一個對等組。它實際上是兩個 UUID 的組合 ? 這就是為什么在構造 PipeID 期間要把組 ID 傳進去的原因。請注重 group 是一個對每一個 shell 應用(包括 shell 的當前對等組)都可用的受保護(protected)變量。


try {
myPipeAdv = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(
PipeAdvertisement.getAdvertisementType());
myPipeAdv.setPipeID( new PipeID(group.getID()) );
} catch (Exception e) {
e.printStackTrace();
return ShellApp.appMiscError;
}
if (myPipeAdv == null) {
println("waitptext: Cannot create a Pipe Advertisement");
return ShellApp.appMiscError;
}
println("created a pipe advertisement...");




創建一條輸入管道
創建了管道廣告之后,我們必須創建一條基于該廣告的輸入管道。通過使用 net.jxta.pipe.Pipe 接口完成這項任務。這里,我們使用從 ShellApp 繼續來的受保護 pipes 變量;pipes 總是包含 shell 的缺省組的缺省管道服務。


try {
myInpPipe = pipes.createInputPipe (myPipeAdv);
} catch (IOException e) {
println("waitptext: Cannot create a Pipe");
return ShellApp.appMiscError;
}
println("created an input pipe based on the advertisement...");




發布管道廣告
現在我們須使該管道廣告對組內的其它對等機可見。我們將使用原始的 Jxta 發現協議來發布該廣告。在一個 P2P 應用產品中,當然,我們可以使用其它方式(也就是說,其它服務)傳播廣告。


try {
myDiscovery = group.getDiscovery();
myDiscovery.publish(myPipeAdv, Discovery.ADV);
} catch( Exception e ) {
println("waitptext: publish of pipe advertisement failed");
return ShellApp.appMiscError;
}
println("published the pipe advertisement to the group...");




等待輸入消息
使該廣告可用之后,我們在該輸入管道上阻塞,以等待傳進來的消息。通過使用 Pipe 實例的 poll() 方法完成這項任務。timeout(超時)值為 0 表示我們將無限期地等待傳入的消息。


println("waiting at the input pipe for a message...");

try {

myMesg = myInpPipe.poll(0);
} catch (IOException e) {
return ShellApp.appNoError;
}




抽取并打印附加文件
假如代碼執行到了這一步,我們將已經接收到一條消息。然后我們根據用戶指定的數據標記創建一個結構化文檔并把這個結構化文檔的文本內容打印到命令窗口。


try {
myInpStream = myMesg.pop (tagName);
println("tagName used is " + tagName);
myStructDoc = StructuredDocumentFactory.newStructuredDocument (
new MimeMediaType ("text/xml"),
myInpStream);
OutputStream out = new ByteArrayOutputStream();

myStructDoc.sendToStream( out );
println("received a message...");
print ( out.toString() );
} catch (Exception e) {
println("waitptext: failed in messge receive");
return ShellApp.appMiscError;
}
return ShellApp.appNoError;
}




這就是 waitptext 的全部!現在您可以用 makeit.bat 編譯這個新命令。

測試 waitptext 命令
啟動 node1(在 shell 目錄)和 node2(在 shell2 目錄)上的 shell 實例。在兩個實例中都輸入如下命令:


jxta> search -f




這將刷新所有現有的活動廣告。因為 Jxta 節點應該免于重啟,廣告在缺省狀態下是持久的。使用 search -f 將確保我們不會有從前面的試驗中遺留下來的廣告。

現在我們可以在 node1 上輸入我們的新命令。您應該看到以下輸出:


JXTA>waitptext dwTag
created a pipe advertisement...
created an input pipe based on the advertisement...
published the pipe advertisement to the group...
waiting at the input pipe for a message...




此時,shell 實例正在等待傳入的消息,

在 node2 實例上,重復我們在前面的 shell 試驗中采用的步驟以:

查找發布的管道廣告(search -r)
生成一條基于該廣告的輸出管道(dwoutpipe = mkpipe -o adv0)
創建一條消息(dwMsg = mkmsg)
把文本文件裝入到一個數據變量中(importfile -f simple.txt dwData)
把文本文件作為一個名為 dwTag 的元素附加上去(put dwMsg dwTag dwData)
通過管道發送消息(send dwMsg dwoutpipe)
回到 node1,我們應該看到發送文件的內容:


tagName used is dwTag
received a message...
<?xml version="1.0"?>
<ShellDoc>
<Item>
This is a simple file for Jxta transfer. It can contain anything.
</Item>
</ShellDoc>
JXTA>




我們已經完成了一個復雜的 shell 擴展的創建,并且揭示了如何用 Jxta 平臺的功能創建 shell 擴展。

談談互操作性
因為我們的所有示例都基于 Java 平臺,一些讀者或許會懷疑 Jxta 的編程語言/平臺的中立性,它是我們在本系列的第一篇論文強調的一個特征。但請記住,我們在這里用的是 Jxta 核心的 Java 實現(Jxta 的參考實現)。另外,請考慮到 Jxta shell 實際上是在 Jxta 核心上工作的、基于 Java 的 Jxta 應用,并且您可以看到我們擁有的是一個完全以 Java 為中心的環境。但平臺和 shell 的其它實現也都是可能的。

事實上,做實際工作的協議交互動作是完全可互操作的。例如:要加入一個對等組,我們須用 Jxta 對等成員資格(Jxta Peer Membership)協議來聯系成員資格對等組服務。要和一個管道溝通,我們必須用 Jxta 管道綁定(Jxta Pipe Binding)協議來聯系管道服務。要共享一個廣告,我們必須用 Jxta 發現(Jxta Discovery)協議在對等組上發布它。假設根據 Jxta 協議規范中描述的基礎協議來實現,那么您就可以在另一個平臺上構建一個能與我們的 Jxta shell 應用輕易地相互操作的 Jxta 和 Jxta shell 的實現。(要了解更多協議,請參閱本系列的第一篇論文。)

下一步:延伸到網絡
Jxta shell 是試驗和學習 P2P 基本原理的重要工具。它簡單而優秀的可擴展性使我們可以輕易地添加新功能。在本文中,我們已經廣泛使用了 shell 的命令行,并粗略地創建了我們自己的復雜的 shell 擴展。

我們大部分時候只在同一個局域網內的一個對等組內的機器上工作。(事實上,我們基本上都在一臺機器上工作)。回想一下本系列的第一篇論文,可以看到 Jxta 對等組的邊界不受底層的物理網絡拓撲結構的限制。在本系列的最后一篇論文中,我們將直接看看 Jxta 發現如何能夠擴展到廣域網(通過路由器)和越過因特網上的防火墻(通過集中服務(rendezvous service))。

參考資料

參加本文討論論壇。


本系列的第 1 部分概述了 Jxta 工程和這種新技術如何能在不硬性規定不必要的規則或具體的應用操作模型的情況下簡化 P2P 應用的設計。


下載本文的源代碼。


請訪問 Jxta 社區的官方站點 Jxta.org,您可在這里找到最新的規范、文檔、源代碼和二進制文件。


假如您對基于 Jini 的技術的更多具體信息感愛好,請參閱 Sing Li 的 Professional Jini 這本書(Wrox Press,2000)。


另一個早期采用者對等工作組已經建立。這個組的戰略會是什么,它與 Jxta 的關系又會是什么,這一點還不清楚。


Todd Sundsted 的位于 developerWorks 的對等計算專欄討論基于 P2P 的技術的所有方面。


要了解一個可與之替換的開放源代碼的 P2P 系統,請查看 Freenet 工程。


來自 IBM 的高級對等連網(Advanced Peer-to-Peer Networking,APPN)提供了強伸縮性、高可用性、安全的網絡解決方案。


IBM 的 Magstar Peer-to-Peer Virtual Tape Server 被設計用來提高數據的可用性及改善您的災難恢復的基礎構造。


在 developerWorks Java 技術專區可找到更多的 Java 參考資料。

關于作者
SingLi 是 Professional Jini 的作者,也是 Wrox 出版社的其他許多書籍的作者。他定期為技術雜志投稿,同時還是 P2P 革命的積極推動者。Sing 是一位咨詢專家和自由撰稿人,可通過 [email protected] 與他聯系。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久精品观看 | 欧美成人一级 | 国产影院在线观看 | 亚洲情av | 黄色成人在线播放 | 一级黄色毛片播放 | 亚洲欧美日韩中文在线 | 亚洲精品一区二区三区大胸 | 黄色高清免费网站 | www.91sese| 日本黄色大片免费 | lutube成人福利在线观看污 | 欧美性生话视频 | 黄色片网站在线免费观看 | 国产在线观看91一区二区三区 | 国产喷白浆10p | 福利在线小视频 | av免费在线观看国产 | 狠狠操操 | 成人三级视频网站 | 美国黄色毛片女人性生活片 | 国产精品久久久久久久久久10秀 | 国产精品av久久久久久网址 | 黄色片视频观看 | 伊人成人免费视频 | 欧美精选一区二区 | 欧美日韩一区二区综合 | 日本高清视频网站www | 婷婷久久久久久 | 亚洲精品一区二区三区大胸 | a网站在线 | 黄色网址免费在线播放 | 午夜神马福利视频 | 欧美日韩在线播放 | 国产成人精品一区在线播放 | 一级成人在线 | 久久一本日日摸夜夜添 | 新久草视频 | 日本成人一区二区三区 | 久久久精品视 | 销魂美女一区二区 |