IPv4定义了3种IP数据包的传输:
单播(unicast)
广播(broadcast)
组播(multicast).
比较一下unicast和multicast两种数据的传输方式可以发现,
当一台主机向多个用户发送信息时,单播对于每一个用户都
要发送一份数据的拷贝,而组播总共只需发送一份数据的拷贝。
这样,组播的使用就大大的节省了带宽,减轻了网络的负载,
从而更加有效的利用了网络的带宽资源.
IP组播和单播的目的地址不同,IP组播的目的地址是组地址.
是从224.0.0.0到239.255.255.255之间的D类IP地址,其中
224.0.0.0到224.0.0.255是被保留的地址,224.0.0.1表示子
网中所有的组播组, 224.0.0.2表示子网中的所有路由器,
224.0.0.5表示OSPF(Open Shortest Path First)路由器,
224.0.0.6表示OSPF指定路由器,224.0.0.12表示DHCP服务器.
在D类地址的分配中,IETF建议遵循以下的原则:
本地机构范围:239.192.0.0~239.192.0.14.
Java 组播程序的例子
import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.NetworkInterface; public class Learn2 { public static void main(String[] args) throws IOException { new MulticastServer().start(); new MulticastClient().start(); } } class MulticastServer extends Thread{ public void run(){ try{ MulticastSocket mcastSocket = new MulticastSocket(7777); InetAddress inetAddress = InetAddress.getByName("230.0.0.1"); mcastSocket.setNetworkInterface(NetworkInterface.getByInetAddress(InetAddress.getLocalHost())); mcastSocket.joinGroup(inetAddress); while (true) { byte [] arb = new byte [100]; DatagramPacket datagramPacket = new DatagramPacket(arb, arb.length); mcastSocket.receive(datagramPacket); System.out.println("Server:"+new String(arb,0,datagramPacket.getLength())); } }catch(Exception dx){ dx.printStackTrace(); } } } class MulticastClient extends Thread{ public void run(){ try{ while(true){ byte [] arb = new byte []{'h', 'e', 'l', 'l', 'o'}; InetAddress inetAddress = InetAddress.getByName("230.0.0.1"); DatagramPacket datagramPacket = new DatagramPacket(arb, arb.length, inetAddress, 7777); MulticastSocket multicastSocket = new MulticastSocket(); multicastSocket.send(datagramPacket); Thread.sleep(1000); } }catch(Exception dx){ dx.printStackTrace(); } } }
基于JGROUPS 的例子:
import java.io.BufferedReader; import java.io.InputStreamReader; import org.jgroups.Address; import org.jgroups.ChannelException; import org.jgroups.JChannel; import org.jgroups.Message; import org.jgroups.ReceiverAdapter; import org.jgroups.View; public class Learn1 { private JChannel channel = null; public Learn1() throws ChannelException{ channel = new JChannel("c:/udp.xml"); } public static void main(String[] args) throws ChannelException { Learn1 learn = new Learn1(); learn.startup(); new SendMessage(learn.channel).start(); } private void startup() throws ChannelException{ channel.setReceiver(new ReceiverMessage()); //channel.setOpt(option, value); channel.connect("FL"); } } class ReceiverMessage extends ReceiverAdapter{ public void receive(Message msg) { System.out.println(msg.getSrc() + ": " + msg.getObject()+" at "+System.currentTimeMillis()); } public void viewAccepted(View new_view) { System.out.println("viewAccepted: " + new_view); } public void suspect(Address suspected_mbr) { System.out.println("suspect: " + suspected_mbr); } } class SendMessage extends Thread{ private JChannel channel; public SendMessage(JChannel channel){ this.channel = channel; } public void run(){ BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); while(true) { try{ System.out.print("> "); System.out.flush(); String line=in.readLine().toLowerCase(); if(line.startsWith("quit") || line.startsWith("exit")) { System.exit(0); } Message msg=new Message(null, null, line); channel.send(msg); }catch(Exception dx){ dx.printStackTrace(); } } } }
使用的 udp.xml 及相关 参数说明