亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

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

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

  學習從頭開始構建 P2P 應用
Sing Li (westmakaha@yahoo.com)
作家,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 變量時的順序是一樣的?,F在,在擴展的幫助下,我們用一個定制命令就可以完成一切事情。

新的命令將被稱為 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 是一位咨詢專家和自由撰稿人,可通過 westmakaha@yahoo.com 與他聯系。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
992tv在线成人免费观看| 久久久久久久av| 美女久久久久久久久久久| 欧美夫妻性生活视频| 亚洲精品v天堂中文字幕| 亚洲人成在线观| 欧美—级a级欧美特级ar全黄| 日本久久久久久久久久久| 国产精品1234| 麻豆国产va免费精品高清在线| 久热精品视频在线| 欧美成人一区在线| 中文字幕日韩欧美在线| 国产精品久久久久77777| 福利视频一区二区| 日韩欧美国产激情| 91精品在线观| 国内成人精品视频| 4444欧美成人kkkk| 久久天天躁狠狠躁夜夜av| 精品久久久在线观看| 最近2019中文字幕在线高清| 另类专区欧美制服同性| 黄网站色欧美视频| 欧美xxxwww| 欧美激情女人20p| 日韩精品在线观看一区二区| 九九热这里只有精品6| 欧美日韩国产一区在线| 92版电视剧仙鹤神针在线观看| 91精品综合久久久久久五月天| 亚洲高清一二三区| 亚洲最大的av网站| 国产精品久久久久久影视| 亚洲精品456在线播放狼人| 久久成人综合视频| 日本精品免费观看| 尤物精品国产第一福利三区| 国产国语videosex另类| 日韩av网址在线观看| 国产乱人伦真实精品视频| 欧美精品中文字幕一区| 欧美日韩xxxxx| 97在线观看视频国产| 国产精品一区二区三区成人| 午夜精品久久17c| 国产亚洲激情在线| 国产精品美女免费| 91wwwcom在线观看| 国产精品视频午夜| 国产热re99久久6国产精品| 国产精品久久久久久久久| 国内偷自视频区视频综合| 精品久久久在线观看| 亚洲性无码av在线| 亚洲综合中文字幕在线观看| 国产成人精品在线视频| 国产精品电影网站| 国产一区二区动漫| 亚洲男人第一网站| 国产精品久久久久久久久免费| 亚洲欧美日韩中文视频| 国产精品福利小视频| 欧美一区二区三区……| 久久久久久九九九| 国产精品久久精品| 亚洲精品成人免费| 久久免费视频网站| 亚洲娇小xxxx欧美娇小| 欧美成人精品一区| 国产精品旅馆在线| 成人久久18免费网站图片| 欧美性生活大片免费观看网址| 日韩中文视频免费在线观看| 欧美日韩国产一区中文午夜| 中文字幕欧美国内| 国产精品久久久久久久久久久久| 欧美中文字幕视频在线观看| 91精品视频一区| 91精品视频在线看| 91久久久久久久| 国产精品三级网站| 国产精品第一视频| 日韩精品中文字幕久久臀| 欧美激情在线观看视频| 国产一区二区丝袜高跟鞋图片| 亚洲天堂开心观看| 精品福利在线视频| 日本在线观看天堂男亚洲| 久久久国产在线视频| 日韩国产精品一区| 国产在线视频一区| 裸体女人亚洲精品一区| 欧美大人香蕉在线| 亚洲成色999久久网站| 久久av中文字幕| 国产精品久久一区| 国产成人+综合亚洲+天堂| 亚洲高清久久网| 97视频在线观看免费| 中文字幕亚洲综合久久筱田步美| 精品露脸国产偷人在视频| 国产精品海角社区在线观看| 91在线免费看网站| 国产日韩欧美在线视频观看| 欧美大片在线免费观看| 国产精品91久久| 欧美一区二区三区免费观看| 国产精品pans私拍| 国产精品va在线播放| 88国产精品欧美一区二区三区| 欧美激情综合色综合啪啪五月| 久久久久久久久久久91| 亚洲欧美精品一区| 中文字幕日本精品| 欧美高清在线视频观看不卡| 少妇高潮久久久久久潘金莲| 欧美夜福利tv在线| 久久久综合av| 国产精品jizz在线观看麻豆| 国产精品综合久久久| 日韩av免费一区| 九九精品视频在线| 91精品国产九九九久久久亚洲| 一区二区三区在线播放欧美| 一区二区三区精品99久久| 欧美精品日韩www.p站| 国产精品网站入口| 国产成人在线一区| 亚洲91精品在线| 亚洲欧美日韩精品久久奇米色影视| 668精品在线视频| 91精品国产乱码久久久久久蜜臀| 欧美激情一区二区三区在线视频观看| 午夜精品久久久久久久白皮肤| 粉嫩老牛aⅴ一区二区三区| 日韩欧美国产黄色| 久久久亚洲欧洲日产国码aⅴ| 亚洲第一福利视频| 伊人久久大香线蕉av一区二区| 午夜精品久久久久久久99热浪潮| 久久精品国产电影| 亚洲精品欧美极品| 欧美专区在线视频| 欧美日本精品在线| 欧美亚洲国产视频| 亚洲国语精品自产拍在线观看| 成人激情电影一区二区| 亚洲图中文字幕| 久久精品国产亚洲一区二区| 一区二区三区视频在线| 久久久久久久久久久av| 亚洲区免费影片| 91中文精品字幕在线视频| 日本不卡高字幕在线2019| 亚洲日本欧美日韩高观看| 国产亚洲激情视频在线| 国语自产精品视频在免费| 日韩精品视频免费在线观看| 中文字幕亚洲无线码a| 91精品国产网站| 亚洲欧美日韩一区在线| 日韩福利在线播放| 欧美在线观看网址综合|