This assignment gives you a chance to familiar with the basic
Java UDP socket programming interface, and Java sleep or (java Timer).
Due: 11:59 PM, Sept.
29, Tuesday. Please see below for submission instruction.
You are given the starting code for the Ping server below. Your job is to write the Ping client and extend the Ping server.
// PingServer.java
import java.io.*;
import java.net.*;
import java.util.*;
/*
* Server to process ping requests over UDP.
*/
public class PingServer
{
private static final double
LOSS_RATE = 0.3;
private static final int AVERAGE_DELAY = 100;
// milliseconds
public static void main(String[] args)
throws Exception
{
// Get
command line argument.
if (args.length != 1) {
System.out.println("Required arguments: port");
return;
}
int port = Integer.parseInt(args[0]);
//
Create random number generator for use in simulating
// packet loss and network delay.
Random
random = new Random();
// Create a
datagram socket for receiving and sending UDP packets
// through the port specified on the command line.
DatagramSocket socket = new DatagramSocket(port);
// Processing loop.
while (true) {
// Create a datagram packet to hold incomming UDP packet.
DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
// Block until the host receives a UDP packet.
socket.receive(request);
// Print the received data.
printData(request);
//
Decide whether to reply, or simulate packet loss.
if (random.nextDouble() < LOSS_RATE) {
System.out.println(" Reply not sent.");
continue;
}
// Simulate network delay.
Thread.sleep((int) (random.nextDouble() * 2 * AVERAGE_DELAY));
// Send reply.
InetAddress
clientHost = request.getAddress();
int clientPort = request.getPort();
byte[] buf = request.getData();
DatagramPacket reply = new DatagramPacket(buf, buf.length, clientHost,
clientPort);
socket.send(reply);
System.out.println("
Reply sent.");
}
}
/*
* Print ping data to the standard output stream.
*/
private static void printData(DatagramPacket request) throws
Exception
{
// Obtain
references to the packet's array of bytes.
byte[] buf = request.getData();
// Wrap
the bytes in a byte array input stream,
// so
that you can read the data as a stream of bytes.
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
// Wrap the byte array output stream in an input stream reader,
// so you can read the data as a stream of **characters**: reader/writer handles
characters
InputStreamReader isr = new InputStreamReader(bais);
// Wrap the input stream reader in a bufferred reader,
// so you can read the character data a line at a time.
// (A line is a sequence of chars terminated by any combination of \r and \n.)
BufferedReader br = new BufferedReader(isr);
// The message data is contained in a single
line, so read this line.
String line =
br.readLine();
// Print host address and
data received from it.
System.out.println(
"Received from " +
request.getAddress().getHostAddress() +
": " +
new String(line) );
}
}
Packet Loss
UDP provides applications with an unreliable transport service, because
messages may get lost in the network due to router queue overflows or other
reasons. In contrast, TCP provides applications with a reliable transport
service and takes care of any lost packets by retransmitting them until they are
successfully received. Applications using UDP for communication must therefore
implement any reliability they need separately in the application level (each
application can implement a different policy, according to its specific needs).
Because packet loss is rare or even non-existent in typical campus
networks, the server in this lab injects artificial loss to simulate the effects
of network packet loss. The server has a parameter LOSS_RATE that determines
which percentage of packets should be lost.
The server also has another
parameter AVERAGE_DELAY that is used to simulate transmission delay from sending
a packet across the Internet. You should set AVERAGE_DELAY to a positive value
when testing your client and server on the same machine, or when machines are
close by on the network. You can set AVERAGE_DELAY to 0 to find out the true
round trip times of your packets.
Compiling and Running
Server
To compile the example server, do the following:
javac PingServer.javaTo run the example server, do the following:
java PingServer portwhere port is the port number the server listens on. Remember that you have to pick a port number greater than 1024, because only processes running with root (administrator) privilege can bind to ports less than 1024.
java -classpath . PingServer portPart II: Your Job
The ping messages in this assignment are formatted in the following way.
PING sequence_number time passwd CRLFwhere sequence_number is 2 bytes, and starts at 0 and increases by 1 for each successive ping message sent by the client; time is 8-byte timestamp (in the format of Java currentTimeMill) encoding when the client sents the message; passwd is ASCII so that a server echoes only valid requests, and CRLF represents the carriage return and line feed characters that terminate the line. It is recommended that you read Chapter 4 of Java Network Programming on i/o issues.
Your Client
You should write the client so that it sends 10 ping requests to the server, separated by one second (Hint: you can Use the Timer and TimerTask classes in java.util.) After sending each packet, the client waits up to one second to receive a reply. If one seconds goes by without a reply from the server, then the client assumes that its packet or the server's reply packet has been lost in the network.
You should write the client so that it starts with the following command:
java PingClient host port passwdwhere host is the name of the computer the server is running on and port is the port number it is listening to. Note that you can run the client and server either on different machines or on the same machine.
Your Server
Please modify the server program to check that the password is
valid. The valid password should be provided when the server starts:
java PingServer port passwd [-delay delay] [-loss
loss]
Bonus
You can extend your program (i.e., both program and message format) to estimate the bandwidth in addition to RTT and loss. There are two ways to estimate bandwidth:
TCP throughput formula: bandwidth = 1.4 Packet Size / (RTT \sqrt(loss));
Use packet pair to measure bandwidth: http://www.hpl.hp.com/personal/Kevin_Lai/projects/nettimer/publications/usits2001/node2.html
If you implement packet pair, please describe your design and how you test the program (e.g., one at zoo, and another machine at home).
Submission
Last Update: September 23, 2009 10:33:30 AM -0400