標籤:
近期由於需要編寫能夠使同一區域網路中的Android用戶端與PC端進行自動匹配通訊功能的程式,學習並實驗了JAVA組播與廣播的內容,記錄一些理解如下:
一.組播(多播)
背景知識:組播使用UDP對一定範圍內的地址發送相同的一組Packet,即一次可以向多個接受者發出資訊,其與單播的主要區別是地址的形式。IP協議分配了一定範圍的地址空間給多播(多播只能使用這個範圍內的IP),IPv4中組播位址範圍為224.0.0.0到239.255.255.255。
JAVA編程:java中通過MulticastSocket執行個體進行通訊,使用時涉及到幾個概念①TTL(Time To Live),每個IP報文都包含一個TTL(是一個數字),報文每被一個路由轉寄一次它的TTL減1,當TTL變為0時,該報文被丟棄②多播組(multicast group),接受者只有加入這個組才能擷取發送到該組的報文(這就確定了組播的對象)
JAVA代碼:
發送端(Android手機):
//-----------------------------------------------------------------------------------------
MulticastSocket mSocket = new MulticastSocket(30001);//產生通訊端並綁定30001連接埠
InetAddress group=InetAddress.getByName("239.0.0.1");//設定多播IP
byte[] buff = "QQ".getBytes("utf-8");//設定多播報文的資料
mSocket.joinGroup(group);//加入多播組,發送方和接受方處於同一組時,接收方可抓取多播報文資訊
mSocket.setTimeToLive(4);//設定TTL
//設定UDP報文(內容,內容長度,多播組,連接埠)
DatagramPacket packet = new DatagramPacket(buff,buff.length,group,30001);
mSocket.send(packet);//發送報文
mSocket.close();//關閉通訊端
//-----------------------------------------------------------------------------------------
接收端(PC):
//-----------------------------------------------------------------------------------------
MulticastSocket s = new MulticastSocket(30001);//產生通訊端並綁定連接埠
InetAddress group = InetAddress.getByName("239.0.0.1");//設定多播IP
s.joinGroup(group);//接受者加入多播組,需要和寄件者在同一組
DatagramPacket packet = new DatagramPacket(buffer , 100);//建立接收報文,以接收通過多重傳遞過來的報文
s.receive(packet);//接收多播報文,程式停滯等待直到接收到報文
s.close();//關閉通訊端
//-----------------------------------------------------------------------------------------
注意事項:
1.windows系統中的TCP/IP 的媒體感知功能會導致組播報出這樣的錯誤:
java.net.SocketException: IP_ADD_MEMBERSHIP failed (out of hardware filters?)
windows7環境下解決方案如下:
使用登錄編輯程式 (運行中鍵入regedit) 來查看下面的登錄機碼: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters (Tcpip類似檔案夾一樣的表徵圖能展開裡面有Parameters,第一次找了很久)
添加以下註冊表值:
數值名稱:DisableDHCPMediaSense 資料類型:REG_DWORD 即(DWORD(32-位)值)建立後右擊修改其值為1,即關閉,重啟機器即可
2.筆者用PC直接連接寬頻開啟程式報錯,切斷寬頻運行正常,猜測為路由器拒絕轉寄組播,此問題有待研究(由於筆者使用Windows hostednetwork建立筆記本自己的網路,將手機加入進來進行測試,所以對程式的測試仍可進行),此為實際程式中放棄使用組播的一個原因
3.不是所有的路由器都支援組播功能,並且一些支援組播的路由器預設為關閉組播的狀態,所以目前使用組播寫程式時需要考慮實際可用性的問題
二.廣播
背景知識:
使用廣播,本網中所有的主機都會受到一份資料副本。廣播使用UDP報文,IPv4使用(255.255.255.255)地址發送廣播,本地廣播絕不會被路由器轉寄,即廣播資訊會被限制在本網之內。
JAVA編程:
UDP單播和廣播類似,主要是IP不同,都是用DatagramSocket對象進行發送
JAVA代碼:
發送端(Android手機)
//-----------------------------------------------------------------------------------------
byte[] buff = "QQ".getBytes("utf-8");//設定報文資訊
DatagramSocket socket=new DatagramSocket();//建立通訊端,參數連接埠號碼不填寫,系統會自動分配一個可用連接埠
//建立報文,包括報文內容,內容長度,報文地址(這裡全1地址即為廣播),連接埠號碼(接受者需要使用該連接埠)
DatagramPacket packet=new DatagramPacket(buff,buff.length,InetAddress.getByName("255.255.255.255"), 30000);
socket.send(packet);//發送報文
socket.disconnect();//斷開通訊端
socket.close();//關閉通訊端
//-----------------------------------------------------------------------------------------
接受端(PC):
//-----------------------------------------------------------------------------------------
DatagramSocket socket=new DatagramSocket(30000);//建立通訊端
byte[] buffer;//建立接收字串
buffer=new byte[35];
DatagramPacket packet = new DatagramPacket(buffer , buffer.length);//建立接收報文,以接收通過廣播傳遞過來的
System.out.println("Listening at UDP(30000)....");
socket.receive(packet);//接收報文,程式停滯等待直到接收到報文
socket.disconnect();//斷開通訊端
socket.close();//關閉通訊端
//--
轉載自:http://blog.sina.com.cn/s/blog_751eaa830101cigu.html
Android開發:組播(多播)與廣播