摘 要 本文介紹了UDP Sockets的基本概念和IP多點傳送的原理
詳細討論了Java中的相關類及使用方法
提供了一個IP多點傳送的開發流程
關鍵詞 Java UDP Sockets
一IP多點傳送
IP多點傳送(multicast delivery)是針對點到點的傳送和廣播傳送兩種方式而言的它是指在一定的組內對其成員進行的廣播是一種有限的廣播組中的某個成員發出的信息組中的其它所有成員都能收到它是UDP Sockets的一個分支
IP多點傳送特別適合與高帶寬的應用例如在網絡上發送視頻和音頻隨著網絡帶寬的不斷提高和網絡通訊質量的不斷改善IP多點傳送還將廣泛地被應用於網上聊天及網上會議分布式數據存儲聯機事務處理交互式游戲等方面另外多點傳送還可以被客戶機用於在網絡上尋找相應的服務器客戶機發送一個多點傳送的請求任何監聽服務器都可以與客戶機連接並開始一個事務
二UDP Socket基礎
使用用戶數據報協議(User Datagram Protocol簡稱UDP)進行會話必須將信息裝配成一定尺寸的小報文當發送一條信息接收方能否收到並返回信息永遠是不確定的如果無法收到返回信息我們就無法確定我們發送的信息是否被接收——它可能在途中丟失接收者返回的響應信息也可能丟失另外接收者也可能忽略我們的信息因此UDP被描述為不可靠的無連接的和面向消息的
創建UDP sockets非常象創建一個郵箱郵箱是使用地址來識別的但是我們不需要為每個發送信息的人構造一個新的郵箱可以在含有發送信息的明信片上寫上目的地址將其放在郵箱中並發送出去接收者可能會長久的等待直到含有信息的明信片到達它的郵箱而明信片上標識了發送者的返回地址
三IP多點傳送的原理
為了支持IP多點傳送某些范圍的IP地址被單獨留出專門用於這個目的這些IP地址是D類地址其地址的最高四比特的位模式為即IP地址的范圍在和之間它們中的每一個IP地址都可以被引用作為一個多點傳送組任何以該IP地址編址的IP報文將被該組中的其它所有機器接收也就是說一個IP地址就相當於一個郵箱另外組中的成員是動態的並隨時間而改變
對於IP多點傳送網間網組管理協議(Internet Group Management Protocol簡稱IGMP)用於管理多點傳送組中的成員支持多點傳送的路由可以使用IGMP決定本地的機器是否贊成加入某個組一個多點傳送路由可以決定是否轉發一個多點傳送報文
影響多點傳送報文的一個重要參數是time-to-live(TTL)TTL用於描述發送者希望傳送的信息能通過多少不同的網絡當報文被路由器轉發報文中的TTL將減一當TTL為零時報文將不再向前發送
在實際使用中我們必須注意下面幾點
這些IP地址只能作為信宿地址使用絕對不能出現在任何信源地址域中也不能出現在源路徑或記錄路徑選項中
由於IP多點傳送是一對多的傳送因此不能利用差錯與控制報文協議(Internet Control Message Protocol簡稱ICMP)產生出錯報文
發送一個信息到一個組發送主機可以不是組中的成員
一些組被Internet Assigned Numbers Authority(IANA)分配保留用於特殊的目的詳情參見ftp://ftpinternicnet/rfc/rfctxt另外避免使用一些保留組從到僅限於本地子網使用建議在和之間任意選取一個IP地址
如果我們選取的組已經被使用與其他機器的通訊將會混亂一旦發生可以退出應用試試其他的地址
當一個機器加入一個多點傳送組它將開始接收該IP多點傳送地址的信息如果多點傳送報文分發到網絡上任何監聽該信息的機器都會有機會接收它對於IP多點傳送沒有一個機制對相同網絡上的機器能否加入該多點傳送組加以限制因此安全性是我們必須考慮的問題之一
選擇的TTL參數應盡可能小一個大的TTL值會不必要地占用Internet帶寬此外還可能破壞不同區域使用相同組的其它的多點傳送通訊
四Java中與IP多點傳送相關的類
javanet包中含有UDP通訊所需要的工具其中包括IP多點傳送
1DatagramPacket類
我們可以使用DatagramPacket類創建一個用於發送的數據報而當接收UDP數據報時可以使用DatagramPacket類讀取數據報中的數據發送者及其它信息
為了創建一個數據報並發送到遠地系統可以使用下面的構造器
Public DatagramPacket(byte ibufint lengthInetAddress iaddrint iport);
ibuf是編碼信息數據的字節數組它的長度length就是數據報放在其中的字節數組的長度iaddr是一個InetAddress對象存儲著接收方的主機名和IP地址等信息iport標識數據報發送到接收主機的端口
為了接收數據報必須使用DatagramPacket構造器其原型為
public DatagramPacket(byte ibufint ilength);
ibuf是指接收的數據報的數據部分 ilength是該部分數據的長度如果 ilength 小於機器接收的UDP數據報的尺寸多余的字節將被Java忽略
另外類中有一些方法(method)可以讓我們得到一些相關的信息
public int getLength();
//得到數據報中數據塊的字節尺寸
public bytegetData();
//得到接收數據報中的數據
public InetAddress getAddress();
//為發送者提供一個 InetAddress對象
public int getPort();
//得到UDP端口
值得注意的是TCP sockets的編程中我們無須將傳送的數據分塊然而當我們創建一個基於UDP的網絡通訊應用程序時必須創建一套方法在運行時刻決定需分割的數據報的長度對於TCP/IP最大的數據報可以含有字節的數據然而主機僅能接收最多字節的數據支持字節的大數據報的平台是利用IP層對數據報進行分割的如果在傳送期間任何含有IP報文的一個數據塊丟失都會造成整個UDP數據報的丟失因此我們在確定應用中數據報尺寸時對其尺寸的合理性一定要謹慎
下面就是分割數據的一個例子
//循環地從輸入流input中讀一行數據
while((nextLine=inputreadLine())!=null){
//定義一個空數據報其尺寸為
mcastBuffer=new byte[];
//如果讀入的數據的長度大於定義的數據報的長度
//則使用定義的長度否則使用讀入數據的長度
if(nextLinelength()>mcastBufferlength){
sendLength=mcastBufferlength;
}else {
sendLenth=nextLinelength();
}
//將讀入的數據轉換為byte類型
lineData=nextLinegetBytes();
//將數據復制到用於創建數據報的byte數組
for(int i=;i mcastBuffer[i]=lineData[i];
}
……創建數據報發送或接收……
}
2MulticastSocket類
Java的 MulticastSocket類是實施IP多點傳送網絡特征的關鍵它允許我們使用多點傳送IP發送或接收UDP數據報
MulticastSocket的構造器為
public MulticastSocket () throws IOException;
//創建一個多點傳送socket
public MulticastSocket(int port)throws IOException;
//在指定端口創建一個多點傳送socket
另外類中其它常用的方法有
public void joinGroup(InetAddress mcastaddr)throws IOException{}
//加入多點傳送組
public void leaveGroup(InetAddress mcastaddr)throws IOException{}
//離開多點傳送組
public synchronized void send(DatagramPacket pbyte ttl) throws IOException{} //發送數據報
public synchronized void receive(DatagramPacket pbyte ttl) throws IOException{} //接收數據報
創建一個DatagramPacket對象之後我們必須相應地創建一個 MulticastSocket對象這樣數據報就可以使用send()方法發送了下面的代碼演示了如何創建 MulticastSocket發送和接收IP多點傳送數據報
int multiPort=;
//定義端口號非超級用戶應使用以上的端口
int ttl=; //設定TTL值
InetAddress multiAddr=InetAddressgetByName(″″) //設定多點傳送IP
byteSmultiBytes={HeO}; //定義一個內容為Hello的數據報
//創建多點傳送數據報
DatagramPacket SmultiDatagram new Datagram Packet(SmultiBytesSmultiByteslengthmultiAddrmultiPort);
MulticastSocket multiSocket=new MulticastSocket(); //創建多點傳送socket
multiSocketsend(SmultiDatagramttl) //發送數據報(不加入到組中)
……
byteRmultiBytes=new byte[]; //定義一個空數據報長度為字節
//創建接收數據報
DatagramPacket RmultiDatagram=new DatagramPacket(RmultiBytesRmultiByteslength);
multiSocketjoinGroup(multiAddr); //加入到多點傳送組中
multiSocketreceive(RmultiDatagram);//接收UDP數據報
……
multiSocketleaveGroup(multiAddr); //離開多點傳送組
multiSocketclose(); //關閉多點傳送 socket
當調用joinGroup()方法時機器將關注沿著網絡傳送屬於特定多點傳送組的任何IP報文也就是說機器擁有了一個郵箱主機還應使用IGMP相應地報告組的使用對於多IP地址的機器應配置數據報發送的接口setInterface(oneOfMyLocalAddrs);
在DatagramSocket中沒有類似 setSo Timeout()的方法設置超時
五IP多點傳送應用程序的開發流程
由於IP多點傳送主要用於同組中成員的交流因此應用程序的開發流程大體如下
創建一個需發送的按規定編址的數據報DatagramPacket;
建立一個用於發送和接收的MulticastSocket;
加入一個多點傳送組
將數據報放入MulticastSocket中傳送出去
等待從MulticastSocket接收數據報
解碼數據報提取信息
根據得到的信息作出回應
重復—步
離開該多點傳送組關閉MulticastSocket
六結束語
在實際應用中發送和接收數據建議分別以單獨的線程同時運行另外如果需在屏幕上顯示建議使用兩個線程在兩個不同的窗口分別負責顯示發送的數據和接收的數據
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27230.html