原文鏈接:http://hbiao68.iteye.com/blog/1943354
使用MulticastSocket實現多點廣播
DatagramSocket只允許數據報發送給指定的目標地址,而MulticastSocket可以將數據報以廣播的方式發送到多個客戶端
若要使用多點廣播,則需要讓一個數據報標有一組目標主機地址,當數據報發出后,整個組的所有所有主機都能收到該數據報。IP多點廣播(或多點發送)實現了將單一信息發送到多個接受者的廣播,其思想是設置一組特殊網絡地址作為多點廣播地址,每一個多點廣播地址都被看做一個組,當客戶端需要發送、接收廣播信息時,加入到改組即可。
MulticastSocket既可以將數據報發送到多點廣播地址,也可以接收其他主機的廣播信息。
MulticastSocket有點像DatagramSocket,事實上MulitcastSocket是DatagramSocket的一個子類,當要發送一個數據報時,可以使用隨機端口創建一個MulticastSocket,也可以在指定端口創建MulticastSocket。MulticastSocket提供了如下3個構造器。
1、MulticastSocket():使用本機默認地址、隨機端口來創建MulticastSocket對象
2、MulticastSocket(int portNumber)使用本機默認地址、指定端口來創建對象
3、MulticastSocket(SocketAddress bindaddr):使用本機指定IP地址、指定端口來創建對象
創建MulticastSocket對象后,還需要將該MulticastSocket加入到指定的多點廣播地址,MulticastSocket使用joinGroup()方法加入指定組;使用leaveGroup()方法脫離一個組。
1、joinGroup(InetAddress multicastAddr):將該MulticastSocket加入指定的多點廣播地址。
2、leaveGroup(InetAddress multicastAddr):讓該MulticastSocket離開指定的多點廣播地址。
應用程序只將數據報包發送給組播地址,路由器將確保包被發送到改組播組中的所有主機。
組播地址:稱為組播組的一組主機所共享的地址。組播地址的范圍在224.0.0.0--- 239.255.255.255之間(都為D類地址 1110開頭)。
備注:如果現在有三台機器A、B、C,三台機器IP地址都不一樣,A\B為server監聽廣播消息,C為客戶端發送廣播消息,個人理解是將A、B兩台機器的MulticastSocket對象綁定在組播地址中的其中一個,然后C客戶端發送消息的組播地址一致,則A、B就能夠接收C發送的消息。
如果MulticastSocket用於接收信息則使用默認地址和隨機端口即可,但是如果用來接收信息,則必須要指定端口,否則發送方無法確定發送數據報的目標端口。
- package hb.brodcast;
- import java.net.DatagramPacket;
- import java.net.InetAddress;
- import java.net.MulticastSocket;
- public class MulticastListener {
- private int port;
- private String host;
- public MulticastListener(String host, int port) {
- this.host = host;
- this.port = port;
- }
- public void listen() {
- byte[] data = new byte[256];
- try {
- InetAddress ip = InetAddress.getByName(this.host);
- MulticastSocket ms = new MulticastSocket(this.port);
- ms.joinGroup(ip);
- DatagramPacket packet = new DatagramPacket(data, data.length);
- //receive()是阻塞方法,會等待客戶端發送過來的信息
- ms.receive(packet);
- String message = new String(packet.getData(), 0, packet.getLength());
- System.out.println(message);
- ms.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- int port = 1234;
- String host = "224.0.0.1";
- MulticastListener ml = new MulticastListener(host, port);
- while (true) {
- ml.listen();
- }
- }
- }
- package hb.brodcast;
- import java.net.DatagramPacket;
- import java.net.InetAddress;
- import java.net.MulticastSocket;
- public class MulticastSender {
- private int port;
- private String host;
- private String data;
- public MulticastSender(String data, String host, int port) {
- this.data = data;
- this.host = host;
- this.port = port;
- }
- public void send() {
- try {
- InetAddress ip = InetAddress.getByName(this.host);
- DatagramPacket packet = new DatagramPacket(this.data.getBytes(), this.data.length(), ip, this.port);
- MulticastSocket ms = new MulticastSocket();
- ms.send(packet);
- ms.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- int port = 1234;
- String host = "224.0.0.1";
- String data = "hello world.";
- System.out.println(data);
- MulticastSender ms = new MulticastSender(data, host, port);
- ms.send();
- }
- }
MulticastSocket用於發送、接收數據報的方法與DatagramSocket完全一樣。但MulticastSocket比DatagramSocket多了一個setTimeToLive(int ttl)方法,該ttl參數用於設置數據報最多可以跨過多少個網絡,當ttl的值為0時,指定數據報應停留在本地主機;當ttl的值為1時,指定數據報發送到本地局域網;當ttl的值為32時,意味着只能發送到本站點的網絡上;當ttl的值為64時,意味着數據報應保留在本地區;當ttl的值為128時,意味着數據報應保留在本大洲;當ttl的值為255時,意味着數據報可發送到所有地方;在默認情況下,該ttl的值為1。