要完成有用的工作
P
P 應用程序中的對等點必須能夠彼此發現對方並與對方交互
在上一篇文章中
Todd 描述了幾種不同的機制
對等點可以使用這些機制彼此發現
他還解釋了每種機制的優缺點
本月
他提供了一種基於 IP 多播的發現的實現
在軟件實體能夠參與具有 P
P 應用程序特征的直接的對等交互之前
該實體必須發現將要與之交互的適當的對等點
所有可行的 P
P 體系結構都提供一種針對發現問題的解決方案
上一次
我們研究了實現發現的幾種不同的方法
本月
我將描述其中一種機制的實現
讓我們通過回顧來開始今天的討論
再訪發現
對等點發現使 P
P 應用程序中的對等點能夠彼此定位以便相互之間可以交互
實現對等點發現服務有多種方法
最簡單的機制是顯式點到點配置
這種機制通過要求每個對等點知道所有它可能與之交互的其它對等點
並與它們相連
來進行工作
點到點配置的主要優點是簡單
它的主要缺點是缺乏靈活性並且缺少擴展到對等點的大型網絡的能力
發現的另一個公共模型是使用中央目錄作為中介
該模型在許多傳統的
非 P
P 分布式類型的應用程序中間很流行
其優點是很好理解
對等點向中央目錄注冊自己的存在
並使用中央目錄定位其它對等點
這種模型的主要優點是易於管理和擴展的能力
但是
其集中化設計會導致單點故障
因此它對自然力或網上沖浪人數增加所帶來的危害缺乏抵御能力
許多流行的 P
P 應用程序使用網絡模型而不是中央目錄
在網絡模型中
單個對等點只知道局域網絡上的對等點身份
每個對等點都作為那些與之相連的對等點的目錄
對等點通過向相鄰對等點傳播目錄查詢並返回相關的響應來進行合作
這種模型的主要優點是沒有集中化
它的主要缺點是由於傳播查詢耗費了大量的網絡和處理能力
上面三種機制有無數種變體
不討論這些變體了
讓我們繼續前進並研究另一種發現機制
IP 多播發現
就每個對等點維護自己的目錄這點而言
多播模型類似於網絡模型
但是
對等點不通過合作來實現大規模網絡查詢
另外
對等點利用網絡本身提供的特性(IP 多播)來定位和標識其它對等點
IP 多播是無連接和不可靠的(不象 TCP/IP 是面向連接和可靠的)
雖然它使用 IP 數據報
但是不象單播 IP 數據報那樣是從一台主機發送到另一台主機
多播 IP 數據報可以同時發往多台主機
對等點定期使用 IP 多播來宣布自己的存在
宣布包含了它們的主機名和一個用於正常通信的端口
對此消息感興趣的對等點檢測這個消息後
抽取出主機名和端口號
並使用該消息建立一個通信通道
回顧已經足夠了
讓我們開始研究代碼吧
簡單的客戶機與服務器
我們將從一個簡單的示例開始
該示例演示了兩個進程如何使用 IP 多播進行通信
為了簡化演示
我將分別從客戶機和服務器進程這兩個方面來介紹示例
P
P 應用程序通常會實現這兩個進程
將它們劃分為客戶機或服務器並不容易
在本例中
服務器進程進行循環並等待數據報包的到來
每接收到一個包
服務器就會向控制台打印一條簡短的診斷消息
客戶機角色要簡單得多 — 它多播單個數據報包並退出
清單
和
說明了這兩部分是如何組合在一起的
代碼中的注釋說明了正在發生的事情
清單
簡單服務器
public
class Server
{
public
static
void
main(String [] arstring)
{
try
{
// Create a multicast datagram socket for receiving IP
// multicast packets
Join the multicast group at
//
port
MulticastSocket multicastSocket = new MulticastSocket(
);
InetAddress inetAddress = InetAddress
getByName(
);
multicastSocket
joinGroup(inetAddress);
// Loop forever and receive messages from clients
Print
// the received messages
while (true)
{
byte [] arb = new byte [
];
DatagramPacket datagramPacket = new DatagramPacket(arb
arb
length);
multicastSocket
receive(datagramPacket);
System
out
println(new String(arb));
}
}
catch (Exception exception)
{
exception
printStackTrace();
}
}
}
清單
簡單客戶機
public
class Client
{
public
static
void
main(String [] arstring)
{
try
{
// Create a datagram package and send it to the multicast
// group at
port
byte [] arb = new byte [] {
h
e
l
l
o
};
InetAddress inetAddress = InetAddress
getByName(
);
DatagramPacket datagramPacket =
new DatagramPacket(arb
arb
length
inetAddress
);
MulticastSocket multicastSocket = new MulticastSocket();
multicastSocket
send(datagramPacket);
}
catch (Exception exception)
{
exception
printStackTrace();
}
}
}
包中的兩個類使它運行
DatagramPacket 類保存了 IP 數據報包中包含的數據
MulticastSocket 類創建一個調整到一個特定多播組的多播套接字
發現組件
盡管上述示例是一個很好的 IP 多播的演示
但它沒有說明實現基於 IP 多播的對等點發現需要什麼
要使它有用
我們需要一個功能不僅限於發送和接收包的軟件組件
理想情況下
這個組件將了解它所接收的包的源對等點
並適當地丟棄一些信息
這些信息是關於那些它認為已經消失
死亡或以其它方式離去的對等點的
在這個新設計中
對等點是一個多播組的成員
請牢記
發送到多播組的消息會透明地路由到該組的所有成員
設計包括兩個核心類和三個接口(我使用術語
接口
似乎不太嚴謹 — 在技術上是一個接口和兩個抽象類)
Member 類的實例是一個多播組的成員
這個類管理所有的通信細節
MemberManager 類的一個實例負責了解參與多播組的其它成員
對等點通過向多播組發送一個消息
來向屬於多播組中的對等點宣布自己的存在
每個消息包含關於發送消息的對等點的信息 — 通常是主機名和用於正常(與發現無關)通信的端口
Member 類和 MemberManager 類對這些消息的內容幾乎一無所知
對該信息的訪問權屬於使用這兩個類的應用程序
有三個接口跨越了消息傳遞/發現層和使用它的應用程序層之間的邊界
它們是 Reference 抽象類
Message 接口和 MessageFactory 抽象類
應用程序必須提供這三個接口的實現
Reference 抽象類定義了對多播組成員的引用
MemberManager 類管理一個引用集
應用程序將實現這個類的一個具體版本
它將包含應用程序所需要的任何引用邏輯
該類定義了兩個方法
名稱是 equalsInternal() 和 hashCodeInternal()
並且重新定義了 equals() 和 hashCode() 方法來調用這些方法
它通過這樣做來強制實現者為這兩個關鍵功能提供實現 — MemberManager 依賴於它們
Message 接口定義了通過網絡代碼交換的消息數據的應用程序視圖
應用程序將該消息看作是相對於應用程序運行范圍的高級概念 — 類似於主機名和端口的概念
網絡代碼希望發送一個由字節組成的包
Message 接口的實現定義了如何將這些高級信息與字節相互轉換
引用是信息的一個關鍵部分
所有消息都必須包含
因此該接口要求實現提供用於讀和寫 reference 的方法
問題的最後部分是 MessageFactory 抽象類
這個類定義了生成新的 Message 實例的機制
深藏在 Member 類內的網絡代碼使用一個工廠來創建從多播數據報中抽取出的數據的 Message 實例
每個 MessageFactory 實例擁有一個隨機生成的身份
它使用這個身份來從接收的消息中濾出要發送的消息
總之
這五個類和接口(Member
MemberManager
Reference
Message 和 MessageFactory)構成了一個用於進行對等點發現的簡單框架
當然
還有可以改進的空間
可以很容易地添加一種基於事件的機制
用於向感興趣的偵聽器通知成員的出現或消失
一種用於過濾所接收消息的靈活機制將很有用
但其實現卻比較困難
我將這些建議留作讀者的作業
Member 類
上面描述的框架的完整源代碼太長了
這裡就不詳細展示了
所以讓我們只研究 Member 類的部分代碼
因為其中包含了操作的大多數內容
更准確地說
操作發生在兩個內部類中
MemberClient 類和 MemberServer 類
請再次考慮第一個示例
它由一個發送 IP 多播數據報的客戶機和一個接收數據報的服務器組成
在本例中(清單
和
)
兩個單獨的應用程序執行這兩項功能
P
P 應用程序中的對等點的行為方式既象客戶機又象服務器
所以我們的 P
P 應用程序應該同時包含兩者才是適合的
清單
MemberClient 類
private
class MemberClient
extends Thread
{
public
void
run()
{
try
{
while (true)
{
try
{
Message message = m_messagefactory
createSendMessage();
Reference reference = message
createReferen
From:http://tw.wingwit.com/Article/program/Java/Javascript/201311/25329.html