Two Simple Examples

Most multicast servers are indiscriminate about who they will talk to. Therefore, it’s easy to join a group—and watch the data that’s being sent to it. Example 14.1 is a MulticastSniffer class that reads the name of a multicast group from the command-line, constructs an InetAddress from that hostname, and then creates a MulticastSocket, which attempts to join the multicast group at that hostname. If the attempt succeeds, it receives datagrams from the socket and prints their contents on System.out. This program is useful primarily to verify that you are receiving multicast data at a particular host. Most multicast data is binary and won’t be intelligible when printed as ASCII.

Example 14-1. Multicast Sniffer

import java.net.*;
import java.io.*;

public class MulticastSniffer {

  public static void main(String[] args) {
  
    InetAddress group = null;
    int port = 0;
  
    // read the address from the command line
    try {
      group = InetAddress.getByName(args[0]);
      port = Integer.parseInt(args[1]);
    }  // end try
    catch (Exception e) {
      // ArrayIndexOutOfBoundsException, NumberFormatException,
      // or UnknownHostException
      System.err.println(
       "Usage: java MulticastSniffer multicast_address port");
      System.exit(1);
    }
  
    MulticastSocket ms = null;
  
    try {
      ms = new MulticastSocket(port);
      ms.joinGroup(group);
      
      byte[] buffer = new byte[8192];
      while (true) {
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
        ms.receive(dp);
        String s = new String(dp.getData(  ));
        System.out.println(s);
      }
    }
    catch (IOException e) {
      System.err.println(e);
    }
    finally {
      if (ms != null) {
        try {
          ms.leaveGroup(group);
          ms.close(  );
        }
        catch (IOException e) {} 
      }
    } 
  
  }

}

The program begins by reading the name and port of the multicast group from the first command-line argument. Next, we create a new MulticastSocket ms on the specified port. This socket joins the multicast group at the specified InetAddress. Then it enters a loop in which it waits for packets to arrive. As each packet arrives, the program reads its data, converts the data to an ISO Latin-1 String, and prints it on System.out. Finally, when the user interrupts the program or an exception is thrown, the socket leaves the group and closes itself.

MBONE session announcements are broadcast to the multicast group http://sap.mcast.net on port 9,875. You can use this program to listen to those announcements. Generally, if you’re connected to the MBONE (not all sites are), then you should see a site announcement pop through within the first minute or two. In fact, you’ll probably see a lot more. I collected about a megabyte and a half of announcements within the first couple of minutes I had this program running. I show only the first two here:

% java MulticastSniffer sap.mcast.net 9875
úv=0
o=ellery 3132060082 3138107776 IN IP4 131.182.10.250
s=NASA TV - Broadcast from NASA HQ
i=NASA TV Multicasting from NASA HQ
u=http://www.nasa.gov/ntv
[email protected]     (Ellery D. Coleman)
p=+202 651 8512
t=3138107776 3153918976
r=15811200 15811200 0
a=recvonly
a=tool:FVC.COM I-Caster V3.1/3101, Windows95/NT
a=cat:Corporate/Events
m=audio 23748 RTP/AVP 0
c=IN IP4 224.2.203.38/127
m=video 60068 RTP/AVP 31
c=IN IP4 224.2.203.37/127
b=AS:380
a=framerate:9
a=quality:8
a=grayed:0
4 224.2.255.115/15
.77/25
4 RTP wbbesteffort
c=IN IP4 224.2.224.41/25

 ¡_v=0
o=dax 3137417804 3141052115 IN IP4 horla.enst.fr
s=VREng UDP (Virtual Reality Engine)
i=Virtual Reality Engine: Distributed Interactive 3D Multicast 
navigator in Virtual Worlds. For more information and downloading, see 
URL: http://www.infres.enst.fr/net/vreng/.
u=http://www.infres.enst.fr/net/vreng/
e=Philippe Dax (ENST) <[email protected]>
p=Philippe Dax (ENST) +33 (0) 145817648
t=0 0
a=tool:sdr v2.9
a=type:test
m=dis 62239 RTP 99
c=IN IP4 224.2.199.133/127
/3
m=mdesk 64538 RTP/AVP mdesk
c=IN IP4 224.2.160.68/3
e please stop your receiving programs and the stream should stop from 
coming to you.
u=http://tv.funet.fi/ohjelmat/index.html
e=Harri Salminen <[email protected]>
p=Harri Salminen +358 400 358 502
t=3085239600 3299658800
a=tool:CDT mAnnouncer 1.1.2
a=type:broadcast
m=audio 4004 RTP/AVP 0
c=IN IP4 239.239.239.239/40
a=ptime:40
m=video 6006 RTP/AVP 31
c=IN IP4 239.239.239.239/40
m=whiteboard 4206 udp wb
c=IN IP4 224.239.239.245/48

MBONE session announcements are not pure ASCII text. In particular, they contain a lot of embedded nulls as well as various characters with their high bit set. Consequently, I’ve had to take a few liberties with the output to print it in this book. To really handle MBONE session announcements, you’d have to parse the relevant ASCII text out of the binary format and display that. Peter Parnes has written a Java program called mSD that does exactly that. If you’re interested, you can find it at http://www.cdt.luth.se/~peppar/progs/mSD/. However, since this is a book about network programming and not parsing binary file formats, we’ll leave our example here and move on to sending multicast data. Example 14.2 is a MulticastSender class that sends data read from the command-line to a multicast group. It is fairly simple overall.

Example 14-2. MulticastSender

import java.net.*;
import java.io.*;


public class MulticastSender {

  public static void main(String[] args) {
  
    InetAddress ia = null;
    int port = 0;
    byte ttl = (byte) 1;
  
    // read the address from the command line
    try {
      ia = InetAddress.getByName(args[0]);
      port = Integer.parseInt(args[1]);
      if (args.length > 2) ttl = (byte) Integer.parseInt(args[2]);
    }
    catch (Exception e)  {
      System.err.println(e);
      System.err.println(
       "Usage: java MulticastSender multicast_address port ttl");
      System.exit(1);
    }
  
    byte[] data = "Here's some multicast data
".getBytes(  );
    DatagramPacket dp = new DatagramPacket(data, data.length, ia, port);
  
    try {
      MulticastSocket ms = new MulticastSocket(  );
      ms.joinGroup(ia);
      for (int i = 1; i < 10; i++) {
        ms.send(dp, ttl);
      }
      ms.leaveGroup(ia);
      ms.close(  );
    }
    catch (SocketException se) {
      System.err.println(se);
    }
    catch (IOException ie) {
      System.err.println(ie);
    }  
  
  }

}

Example 14.2 reads the address of a multicast group, a port number, and an optional TTL from the command line. It then stuffs the string "Here's some multicast data " into the byte array data using the getBytes( ) method of java.lang.String, and places this array in the DatagramPacket dp. Next, it constructs the MulticastSocket ms, which joins the group ia. Once it has joined the group, ms sends the datagram packet dp to the group ia 10 times. The TTL value is set to one to make sure that this data doesn’t go beyond the local subnet. Having sent the data, ms leaves the group and closes itself.

Run MulticastSniffer on one machine in your local subnet. Listen to the group all-systems.mcast.net on port 4,000 like this:

% java MulticastSniffer all-systems.mcast.net 4000

Then send data to that group by running MulticastSender on another machine in your local subnet. You can also run it in a different window on the same machine, though that’s not as exciting. However, you must start running the MulticastSniffer before you start running the MulticastSender. Send to the group all-systems.mcast.net on port 4,000 like this:

% java MulticastSender all-systems.mcast.net 4000

Back on the first machine you should see this output:

Here's some multicast data
Here's some multicast data
Here's some multicast data
Here's some multicast data
Here's some multicast data
Here's some multicast data
Here's some multicast data
Here's some multicast data
Here's some multicast data

For this to work beyond the local subnet, the two subnets will each have to have multicast routers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.79.59