2011年10月28日 星期五

[ Java 文章收集 ] 網路相關 : Java Multicasting


轉載自 這理
What is multicast :
All the socket and datagram programs that we have seen so far are for point-to-point communication and are usually called unicast. Although point-to-point communications are good for many applications, there are situations in which you need a different model. For example, in a electronic conferencing system, there is a one-to-many conversation : people may come and go as they wish, the speaker (who may change from time to time) addresses a group rather than an individual. Although broadcast (ie. one-to-all communication) may serve for this purpose, its overhead is too large that make it an impractical solution.
Another approach is to use many unicasts for the one-to-many model. Although it is much efficient than broadcast, it is still inefficient since it duplicates data needlessly which is shown in the following figure. In the figure, one computer sends four copies of a message to four receivers.


As a result, a model called multicast was developed. By the definition of Wikipedia, multicast is the delivery of information to multiple destinations simultaneously using the most efficient strategy to deliver the messages over the network over each link of the network only once and only create copies when the links to the destinations split. This can be shown in the following figure. As in the previous example, the message is only transmitted once across the network.


The word "Multicast" is typically used to refer to IP Multicast, which is a protocol for efficiently sending to multiple receivers at the same time on TCP/IP networks, by use of a multicast address. (Can you tell me now which IP protocol, TCP or UDP, is used in multicasting?) In summary, there are two issues need to be addressed more. One issue is related to how messages are transmitted. Usually, the task is handled by multicast-capable routers (or, in short, multicast routers or mrouters). With multicast routers, programmers will be relieved from complex routing tasks. However, one major disadvantage is that, if no multcast routers exist between any two hosts, there is no way for these two hosts to communicate using multicasting.
The other issue is related to the multicast address which is actually the class D address (in the range 224.0.0.0 to 239.255.255.255) that we discussed earlier. Therefore, every IP datagram whose destination address starts with "1110" is an IP Multicast datagram. The remaining 28 bits identify the multicast "group" the datagram is sent to. There are several special multicast groups, say "well known multicast groups", you should not use in your particular applications due the special purpose they are destined to :
* 224.0.0.1 is the all-hosts group. If you ping that group, all multicast capable hosts on the network should answer, as every multicast capable host must join that group at start-up on all it's multicast capable interfaces. To see if there is any host that is multicast capable, do a ping 224.0.0.1 (or put an extra -s option for Solaris).
* 224.0.0.2 is the all-routers group. All multicast routers must join that group on all it's multicast capable interfaces. To see if your local subnet supports multicast, do a ping all-routers.mcast.net and see if there is any response. If so, you subnet has a router that supports multicast.
* 224.0.0.4 is the all DVMRP routers, 224.0.0.5 the all OSPF routers, 224.0.013 the all PIM routers, etc.

When a host wants to send data to a multicast group, it puts that data in multicast datagrams, which are nothing more than UDP datagrams addressed to a multicast group. The only thing an application programmers needs to worry is about how long can a UDP datagram can live which is controlled by a Time-To-Live value. The valid value is in the range 0 to 255; it is roughly interpreted as the number of routers that a packet can pass through before it is discarded. However, a good TTL value is hard to determine. Usually, a TTL value of 16 limits the packet to the local area, generally one organization. A TTL of 127 sends the packet around the world. However, many organizations put hard restriction on multicast packets for performance reason.

java.net.MulticastSocket 範例代碼 :
java.net.MulticastSocket is used on the client-side to listen for packets that the server broadcasts to multiple clients. 如果你查一下 文件,其實 MulticastSocket 直接繼承 DatagramSocket. 底下是幾個 MulticastSocket 的使用範例 :
- Example1 : 這一個範例是讓每一個 MulticastPeer 的程式同時成為 server 也是 client。它的工作是先送出一個訊息,並等待收完三個訊息以後結束
- MulticasePeer.java :
  1. package john.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.DatagramPacket;  
  5. import java.net.InetAddress;  
  6. import java.net.MulticastSocket;  
  7.   
  8. public class MulticasePeer  
  9. {  
  10.     public static int port = 6789;  
  11.     public static String bcastIP = "224.5.5.5"// Pick up one D class IP for multicast address.  
  12.     public static String testData = "Hello";  
  13.     public static int PACKET_BUFFER_SIZE = 1024;  
  14.   
  15.     public static void main(String[] args)  
  16.     {  
  17.         MulticastSocket s = null;  
  18.         try  
  19.         {  
  20.             InetAddress group = InetAddress.getByName(bcastIP);  
  21.             // The client must have a MulticastSocket bound to this port.  
  22.             s = new MulticastSocket(port);  
  23.             byte[] m = testData.getBytes();  
  24.             // 用來輸出的 datagram  
  25.             DatagramPacket dp = new DatagramPacket(m, m.length, group, port);  
  26.             s.joinGroup(group);  
  27.             s.send(dp);  
  28.   
  29.             byte[] buffer = new byte[PACKET_BUFFER_SIZE];  
  30.             int cnt = 0;  
  31.             // 輸出一筆, 接收三筆後結束 (或收到 "bye")  
  32.             while (cnt < 3)  
  33.             {  
  34.                 DatagramPacket indp = new DatagramPacket(buffer, buffer.length);  
  35.                 s.receive(indp);  
  36.                 String msg = new String(indp.getData(), 0, indp.getLength());  
  37.                 System.out.println("\t[Received]: " + msg);  
  38.                 if (msg.equals("bye")) break;  
  39.                 cnt++;  
  40.             }  
  41.             s.leaveGroup(group);  
  42.         }  
  43.         catch (IOException ioe)  
  44.         {  
  45.             ioe.printStackTrace();  
  46.         }  
  47.         catch (Exception e)  
  48.         {  
  49.             e.printStackTrace();  
  50.         }  
  51.     }  
  52. }  

- Example 2 :
這個範例分成 client 和 server. client 是 MulticastSniffer 只是從群組中不斷的將資料擷取下來. 而 server 是 MulticastSender 負責送出多個訊息.
- MulticastSniffer.java : Sniffer client
  1. package john.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.DatagramPacket;  
  5. import java.net.InetAddress;  
  6. import java.net.MulticastSocket;  
  7.   
  8. public class MulticastSniffer {  
  9.     public static int PACKET_BUFFER_SIZE = 65509;  
  10.     public static int port=6789;  
  11.     public static String bcastIP = "224.5.5.5"// Pick up one D class IP for multicast address.  
  12.       
  13.     public static void main(String[] args) {  
  14.         InetAddress ia = null;  
  15.         byte[] buffer = new byte[PACKET_BUFFER_SIZE];  
  16.         DatagramPacket dp = new DatagramPacket(buffer, buffer.length);  
  17.         try{  
  18.             ia = InetAddress.getByName(bcastIP);  
  19.         }catch(Exception e){e.printStackTrace();System.exit(1);}  
  20.         try{              
  21.             MulticastSocket ms = new MulticastSocket(port);  
  22.             ms.joinGroup(ia);  
  23.             String s;  
  24.             while(true)  
  25.             {  
  26.                 ms.receive(dp);  
  27.                 s = new String(dp.getData(), 0, dp.getLength());  
  28.                 System.out.println("\t[Received] "+s);  
  29.             }  
  30.         }catch(IOException ioe){  
  31.             ioe.printStackTrace();  
  32.         }  
  33.     }  
  34. }  

- MulticastSender.java : Sender as Server
  1. package john.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.DatagramPacket;  
  5. import java.net.InetAddress;  
  6. import java.net.MulticastSocket;  
  7.   
  8. public class MulticastSender {  
  9.     public static int PACKET_BUFFER_SIZE = 65509;  
  10.     public static int port=6789;  
  11.     public static String bcastIP = "224.5.5.5"// Pick up one D class IP for multicast address.  
  12.     public static String testData = "Here's some Multicast data";  
  13.     public static void main(String[] args) {  
  14.         InetAddress ia = null;  
  15.         byte[] data = new byte[testData.length()];  
  16.         try{  
  17.             ia = InetAddress.getByName(bcastIP);  
  18.         }catch(Exception e){e.printStackTrace();System.exit(1);}  
  19.           
  20.         data = testData.getBytes();  
  21.         DatagramPacket dp = new DatagramPacket(data, data.length, ia, port);  
  22.           
  23.         try{  
  24.             MulticastSocket ms = new MulticastSocket();  
  25.               
  26.             // you can try to use different TTL value here for ms.  
  27.             // ms.setTimeToLive(16);  
  28.               
  29.             ms.joinGroup(ia);  
  30.             for(int i=0; i<10; i++) ms.send(dp);  
  31.               
  32.             ms.leaveGroup(ia);  
  33.             ms.close();  
  34.         }catch(IOException ioe){ioe.printStackTrace();}  
  35.     }  
  36. }  

補充說明 :
TCP/IP, UDP & Multicasting Through Java's Socket
Since birth of network programming, it has been error-prone, difficult, and complex. The programmer had to know many details about the network and sometimes even the hardware. You usually needed to understand the various layers of the networking protocol, and there were a lot to different functions in each networking library concerned with connecting, packing, unpacking blocks of information, handshaking, etc.
This message was edited 7 times. Last update was at 13/04/2011 14:11:23

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...