Assignment 2 Udp Pinger In Java

Assigned: Tuesday, February 19, 2013
Due: Tuesday, March 19, 2013

Contents (hide)

Description

The goal of this assignment is to help you become familiar with socket programming in Java or Python using both TCP and UDP sockets. We'll be implementing a -like client-server application that allows a client to measure the round-trip time (RTT) to a server.

Because we're limited to running the programs on-campus where there will be little delay and very little loss, the server will add some artificial delay and ignore some ping requests (for UDP) to simulate packet loss.

PingClient

  • The ping client will accept three command-line arguments: hostname, port, and protocol.
    • hostname - the name of the server
    • port - the port the server is running on

    Note that for ODU-CS machines, the port must be between 10001-11000. Also, these ports are only accessible to clients that are on campus.

    • protocol - either TCP or UDP (all caps)
  • As with the Program 1, if any of the arguments are incorrect, exit after printing an error message of the form , where x is the argument number.
  • Depending on the protocol given, the ping client will either setup a TCP connection to send each message or send UDP datagrams. For TCP, this application-level protocol is non-persistent, meaning that there is one request-reply exchange per TCP connection.
  • The client will send 10 messages to the server in the following format:
where is the word "PING", is the ping sequence number (between 0-9), and is the time (in milliseconds) that the message was created and sent
  • The client will not send a new ping until the previous ping has been answered.
  • On a single line, the client will print the message that it sends to the server and the round-trip time for the ping or a if the reply is not received in 1 second (for UDP only).
  • After receiving the 10th reply (or after its timeout), the client will print a summary with a format similar to that displayed by the Unix command. Example:

Print the average RTT with up to 2 digits after the decimal.

PingServer

  • The ping server is essentially an echo server (whatever data is sent will be returned).
  • The ping server will accept 2 required command-line arguments: port and protocol.
    • port - the port the server is running on
    • protocol - either TCP or UDP (all caps)
  • The ping server will accept 1 optional command-line argument: seed.
    • seed - a to seed the random number generator for generating delays and lost packets
  • As with the Program 1, if any of the arguments are incorrect, exit after printing an error message of the form , where x is the argument number.
  • After a ping request has been received by the UDP server, the server will determine if it should ignore the packet or respond to it (simulating losses). Default loss rate is 25%.
  • If the ping will be responded to (i.e., it is not dropped), the server will first wait for a random amount of time to simulate network delay (average 150 ms each way).
  • On a single line, the server will print the IP address and port of the client, the client's ping message, and the server's action.

The server's action will either be "" if the ping was ignored or "" .

  • The ping server will keep running until the user presses Ctrl-C.

For TCP, the server will close the client connection after each ping reply is sent.

Rules

  • As with all projects, you are not permitted to work with anyone else (even students not in the class) - all of the coding and documentation must be your own.
  • Your programs must compile and run on the CS Unix machines.
  • You must write neat code and document it well. You will lose points for sloppy programs that contain little or no comments.

Testing

A large part of your program's grade will be determined by how well it handles a set of inputs. You should test your program rigorously before submitting. Because your programs will be run and tested using a script, you must format your output exactly as I have described or you will lose points.

Since Java and Python use different random number generators, they will produce different results with the same seed. So, I'm providing separate examples for each language.

Java Examples

Example 1

java PingClient Usage: java PingClient hostname port protocol protocol - {TCP, UDP} java PingServer Usage: java PingServer port protocol [seed] protocol - {TCP, UDP}

Example 2

java PingClient atria three TCP ERR - arg 2 java PingServer 10002 tcp ERR - arg 2

Example 3

atria> java PingServer 10002 TCP 123 128.82.4.244:33968> PING 0 1360792272731 ACTION: delayed 216 ms 128.82.4.244:33969> PING 1 1360792272949 ACTION: delayed 297 ms 128.82.4.244:33970> PING 2 1360792273248 ACTION: delayed 75 ms 128.82.4.244:33971> PING 3 1360792273324 ACTION: delayed 182 ms 128.82.4.244:33972> PING 4 1360792273508 ACTION: delayed 241 ms 128.82.4.244:33973> PING 5 1360792273751 ACTION: delayed 262 ms 128.82.4.244:33974> PING 6 1360792274014 ACTION: delayed 214 ms 128.82.4.244:33975> PING 7 1360792274230 ACTION: delayed 21 ms 128.82.4.244:33976> PING 8 1360792274252 ACTION: delayed 238 ms 128.82.4.244:33977> PING 9 1360792274492 ACTION: delayed 173 ms sirius> java PingClient atria 10002 TCP PING 0 1360792272731 RTT: 217 ms PING 1 1360792272949 RTT: 298 ms PING 2 1360792273248 RTT: 76 ms PING 3 1360792273324 RTT: 183 ms PING 4 1360792273508 RTT: 242 ms PING 5 1360792273751 RTT: 263 ms PING 6 1360792274014 RTT: 215 ms PING 7 1360792274230 RTT: 22 ms PING 8 1360792274252 RTT: 239 ms PING 9 1360792274492 RTT: 174 ms ---- PING Statistics ---- 10 packets transmitted, 10 packets received, 0% packet loss round-trip (ms) min/avg/max = 22/192.9/298

Notes:

  • The delays the server uses should be the same with the same seed, but the timestamps in the client's ping message will not since they depend on the time the program was run.
  • With TCP since you are creating a new connection for each PING sent, the client's port number will be different each time.
  • The RTTs that the client reports should be similar to the example, but may not be exact.

Example 3

atria> java PingServer 10002 UDP 123 128.82.4.244:44229> PING 0 1360792326564 ACTION: delayed 297 ms 128.82.4.244:44229> PING 1 1360792326863 ACTION: delayed 182 ms 128.82.4.244:44229> PING 2 1360792327046 ACTION: delayed 262 ms 128.82.4.244:44229> PING 3 1360792327309 ACTION: delayed 21 ms 128.82.4.244:44229> PING 4 1360792327331 ACTION: delayed 173 ms 128.82.4.244:44229> PING 5 1360792327505 ACTION: delayed 44 ms 128.82.4.244:44229> PING 6 1360792327550 ACTION: delayed 19 ms 128.82.4.244:44229> PING 7 1360792327570 ACTION: not sent 128.82.4.244:44229> PING 8 1360792328571 ACTION: not sent 128.82.4.244:44229> PING 9 1360792329573 ACTION: delayed 262 ms sirius> java PingClient atria 10002 UDP PING 0 1360792326564 RTT: 299 ms PING 1 1360792326863 RTT: 183 ms PING 2 1360792327046 RTT: 263 ms PING 3 1360792327309 RTT: 22 ms PING 4 1360792327331 RTT: 174 ms PING 5 1360792327505 RTT: 45 ms PING 6 1360792327550 RTT: 20 ms PING 7 1360792327570 RTT: * PING 8 1360792328571 RTT: * PING 9 1360792329573 RTT: 263 ms ---- PING Statistics ---- 10 packets transmitted, 8 packets received, 20% packet loss round-trip (ms) min/avg/max = 20/158.62/299

Python Examples

Example 1

python PingClient.py Usage: python PingClient.py hostname port protocol protocol - {TCP, UDP} python PingServer.py Usage: python PingServer.py port protocol [seed] protocol - {TCP, UDP}

Example 2

python PingClient.py atria three TCP ERR - arg 2 python PingServer.py 10002 tcp ERR - arg 2

Example 3

atria> python PingServer.py 10002 TCP 123 128.82.4.244:34747> PING 0 1361211379146 ACTION: delayed 15 ms 128.82.4.244:34748> PING 1 1361211379163 ACTION: delayed 26 ms 128.82.4.244:34749> PING 2 1361211379190 ACTION: delayed 122 ms 128.82.4.244:34750> PING 3 1361211379314 ACTION: delayed 32 ms 128.82.4.244:34751> PING 4 1361211379348 ACTION: delayed 270 ms 128.82.4.244:34752> PING 5 1361211379619 ACTION: delayed 11 ms 128.82.4.244:34753> PING 6 1361211379632 ACTION: delayed 160 ms 128.82.4.244:34754> PING 7 1361211379794 ACTION: delayed 99 ms 128.82.4.244:34755> PING 8 1361211379894 ACTION: delayed 255 ms 128.82.4.244:34756> PING 9 1361211380151 ACTION: delayed 47 ms sirius> python PingClient.py atria 10002 TCP PING 0 1361211379146 RTT: 16 ms PING 1 1361211379163 RTT: 26 ms PING 2 1361211379190 RTT: 123 ms PING 3 1361211379314 RTT: 33 ms PING 4 1361211379348 RTT: 271 ms PING 5 1361211379619 RTT: 12 ms PING 6 1361211379632 RTT: 161 ms PING 7 1361211379794 RTT: 99 ms PING 8 1361211379894 RTT: 256 ms PING 9 1361211380151 RTT: 48 ms ---- PING Statistics ---- 10 packets transmitted, 10 packets received, 0.0% packet loss round-trip (ms) min/avg/max = 12/104.50/271

Notes:

  • The delays the server uses should be the same with the same seed, but the timestamps in the client's ping message will not since they depend on the time the program was run.
  • With TCP since you are creating a new connection for each PING sent, the client's port number will be different each time.
  • The RTTs that the client reports should be similar to the example, but may not be exact.

Example 3 - edited 3/5/13 -MCW

atria> python PingServer.py 10002 UDP 123 128.82.4.244:58353> PING 0 1361211436430 ACTION: not sent 128.82.4.244:58353> PING 1 1361211437433 ACTION: not sent 128.82.4.244:58353> PING 2 1361211438435 ACTION: delayed 32 ms 128.82.4.244:58353> PING 3 1361211438468 ACTION: delayed 11 ms 128.82.4.244:58353> PING 4 1361211438480 ACTION: delayed 99 ms 128.82.4.244:58353> PING 5 1361211438580 ACTION: delayed 47 ms 128.82.4.244:58353> PING 6 1361211438628 ACTION: delayed 100 ms 128.82.4.244:58353> PING 7 1361211438729 ACTION: not sent 128.82.4.244:58353> PING 8 1361211439731 ACTION: not sent 128.82.4.244:58353> PING 9 1361211440733 ACTION: delayed 26 ms sirius> python PingClient.py atria 10002 UDP PING 0 1361211436430 RTT: * PING 1 1361211437433 RTT: * PING 2 1361211438435 RTT: 33 ms PING 3 1361211438468 RTT: 12 ms PING 4 1361211438480 RTT: 100 ms PING 5 1361211438580 RTT: 48 ms PING 6 1361211438628 RTT: 101 ms PING 7 1361211438729 RTT: * PING 8 1361211439731 RTT: * PING 9 1361211440733 RTT: 27 ms ---- PING Statistics ---- 10 packets transmitted, 6 packets received, 40.0% packet loss round-trip (ms) min/avg/max = 12/53.50/101

Notes/FAQs

  • Where can I find information about Java classes?

Java Class Reference

  • Where can I find information about Python functions?

Python Standard Library Reference

  • Can I use the linux.cs.odu.edu alias when running these programs?

No. You must use an actual machine name (atria or sirius). Think about why.

  • How can I get the current time in milliseconds?

Java: See

Python: See

  • How can I set a timeout value on reading from a datagram socket?

Java: See the function in the class.

Python: See the function in the library.

  • How can I format a double to have a certain number of digits after the decimal?

Java: See the class.

Python: See the function.

  • How can I generate a random loss pattern and artificial delay?
Java:
  • Use the class (so put at the beginning of your program).
  • Between your and lines, insert:
private static final double LOSS_RATE = 0.25; private static final int AVERAGE_DELAY = 150; // milliseconds
  • To set the random number generator seed and create the Random object (after you have determined if the user has given you a seed argument), use
// Create random number generator for use in simulating packet loss and network delay. Random random; if (seed == 0) { random = new Random(); } else { random = new Random(seed); }

Note: The object should be created only once in the server program. Do not create new objects for each connection or for each packet received.

  • To determine whether to reply to a ping, use
// Decide whether to reply, or simulate packet loss. if (random.nextDouble() < LOSS_RATE)

If this evaluates to , print 'not sent' and don't send the reply.

If this evaluates to , send the reply.

// Simulate network delay. delay = (int) (random.nextDouble() * 2 * AVERAGE_DELAY); Thread.sleep(delay);

Don't forget to print out the delay amount.

Python:
  • Use (so put at the beginning of your program).
  • Create the following global constants:
LOSS_RATE = 0.25 AVERAGE_DELAY = 150 # milliseconds
  • To set the random number generator seed (after you have determined if the user has given you a seed argument):
# Create random number generator for use in simulating packet loss and network delay. random.seed(seed)
Notes:
  • If , the seed will be set based on the current time of day. This will produce different values each time you run the program.
  • should be called only once in the server program. Do not reset the seed for each connection or for each packet received.
  • To determine whether to reply to a ping, use
# Decide whether to reply, or simulate packet loss. if random.random() < LOSS_RATE

If this evaluates to , print 'not sent' and don't send the reply.

If this evaluates to , send the reply.

# Simulate network delay. delay = (random.random() * 2 * AVERAGE_DELAY) # sleep time in ms time.sleep(delay/1000.0) # accepts time in secs

Don't forget to print out the delay amount.

Submission

You must name your source files PingClient.java and PingServer.java (note the capitalization) or PingClient.py and PingServer.py. Make sure that you submit all files necessary to compile your program. But, do not submit compiled files (.class files).

Directions for submitting your assignment through Blackboard





import java.io.BufferedReader;

import java.io.ByteArrayInputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.util.Random;

/*

* Server to process ping requests over UDP. java PingClient host port

*/

public class PingClient

{

public static void main(String[] args) throws Exception

{

// Get command line argument.

if (args.length != 2) {

System.out.println("Required arguments: host port");

return;

}

String ServerName =args[0];

int port = Integer.parseInt(args[1]);

// Create a datagram socket for receiving and sending UDP packets

// through the port specified on the command line.

DatagramSocket socket = new DatagramSocket();

InetAddress IPAddress =InetAddress.getByName(ServerName);

// Processing loop.

// You should write the client so that it sends

// 10 ping requests to the server, separated by

// approximately one second.

for(int i=0;i<10;i++){

// Create a datagram packet to hold outgoing UDP packet.

//Each message contains

// a payload of data that includes the keyword PING,

// a sequence number, and a timestamp.

long SendTime = System.currentTimeMillis();

String Message = "Ping "+ i + " " + SendTime + "\n";

DatagramPacket request =

new DatagramPacket(Message.getBytes(), Message.length(),IPAddress,port );

socket.send(request);

DatagramPacket reply =

new DatagramPacket(new byte[1024], 1024);

socket.setSoTimeout(1000);

try

{

socket.receive(reply);

}catch(IOException E)

{

}

Thread.sleep(1000);

}

// 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.

}

/*

* 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.

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) );

}

}

Categories: 1

0 Replies to “Assignment 2 Udp Pinger In Java”

Leave a comment

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *