requirement
CSCI690 - Multicast Socket Programming Project
[Objective]
Develop a multicast client program to work in conjunction with a
multicast test stream.
[Requirements]
The multicast client must be able to join any group/port, that is
specified via the command line. E.g.,
mclisten <multicast group> <port>
where multicast group is a class D IP address, and port is a UDP port
number.
The maximum packet size the client must be able to accept is 1024
bytes. The first 32 bits of each packet will contain a sequence
number, beginning with sequence number 0.
For each packet received the program should print the time (delta)
since the last packet was received, the host (ip address) and port the
packet was received from, the packet number, and packet size. E.g.,
86 msec From host:192.168.1.30 port:49404 Packet# 1 64 bytes
29 msec From host:192.168.1.30 port:49404 Packet# 2 64 bytes
27 msec From host:192.168.1.30 port:49404 Packet# 3 64 bytes
[C Socket API]
Utilizing the socket API begin by creating a UDP socket. The socket
address structure should be filled in with the mutlicast group and
port number. Then we can bind to the socket. After we call bind, we
can set the multicast socket options to join the multicast group. At
this point we can enter an infinite loop, call recvfrom and process
the data received.
[Java Socket API]
http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html
http://java.sun.com/docs/books/tutorial/networking/sockets/index.html
sample test program
/**
* mcsend.java - multicast sender test program
* @version 1.0
*
* @author Michael Hutt
* @date 2009-10-05
* javac mcsend.java
* java mcsend 10 64 239.1.1.1 3000 1
*
* This sends 10 packets, 64 bytes each to multicast group 239.1.1.1,
* udp port 3000, with a TTL of 1.
* The packet contains a sequence number in the first 32 bits which should be
* displayed by the receiver.
*
* Although we could use a DatagramSocket, we chose a MulticastSocket so
* that we can set the IP_MUTLICAST_TTL for testing purposes.
*
* @todo
*
*/
import java.io.*;
import java.net.*;
import java.util.regex.Pattern;
public class mcsend {
private static MulticastSocket socket; // multicast uses a UDP socket
private static int packet_count; // number of packets to send
private static int packet_size; // size of packets to be sent - 1024 bytes max
private static String group; // multicast group we're sending to
private static int port; // UDP port number
private static int ttl; // Time To Live
public static void main(String[] args) throws IOException {
int i;
process_cliargs(args);
socket = new MulticastSocket();
socket.setTimeToLive(ttl);
byte[] buf = new byte[packet_size];
InetAddress address = InetAddress.getByName(group);
for (i=0; i<packet_count; i++) {
/* stuff sequence number into first 32 bits of packet */
buf[0] = (byte) (i >>> 24);
buf[1] = (byte) (i >>> 16);
buf[2] = (byte) (i >>> 8);
buf[3] = (byte) (i >>> 0);
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
System.out.println("sending to socket: " + group + ":" + port + " Packet number: " + i);
}
}
/* process the command line arguments */
public static void process_cliargs(String[] args) {
if (args.length < 5) {
die("incorrect number of parameters");
}
packet_count = Integer.parseInt(args[0]);
packet_size = Integer.parseInt(args[1]);
group = args[2];
port = Integer.parseInt(args[3]);
ttl = Integer.parseInt(args[4]);
if (packet_count < 1)
die("must enter a positive value for number of packets");
if (packet_size > 1024)
die("packet size must be less than 1024");
if (port < 1024 || port > 65535)
die("port number must be between 1024 and 65535");
if (!valid_ip(group))
die("invalid group entered - must be a class D address");
if (ttl < 0 || ttl > 255)
die("ttl must be between 0 and 255");
}
/* validate ip address */
public static boolean valid_ip(String group) {
String regex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
if (!Pattern.matches(regex, group)) {
return false;
}
String[] address = group.split("\\.");
/* make sure we have a multicast class D address */
if (Integer.parseInt(address[0]) < 224 || Integer.parseInt(address[0]) > 239)
return false;
for (int n=1; n<=3; n++) {
if (Integer.parseInt(address[n]) < 0 || Integer.parseInt(address[n]) > 255)
return false;
}
return true;
}
/* print error messages and terminate program */
public static void die(String msg) {
System.out.println("usage: mcsend <number of packets> <packet size> <multicast group> <port> <ttl>");
System.out.println("error: " + msg);
System.exit(0);
}
} // end of mcsend class