CS 453: Computer Networks
Programming Assignment 2
Instructor : V. Arun

1. Overview

In this assignment, you will implement a reliable transport protocol for a messaging application. You have previously used UDP and TCP sockets to write network programs. This assignment asks you to pretend that TCP does not exist and implement reliable transport yourself on top of UDP.

Your goal is to write (possibly identical) UDP-based sender and receiver chat client programs that communicate through a chat server we maintain. You can also run the chat server yourself on your local machine, but using the common chat server will probably be a more interesting experience. Your chat client's transport protocol should implement the following:

  1. Part A: ensure reliable, in-order delivery of a stream of text from a file;
  2. Part B: implement a command to efficiently transfer a file using a pipelined protocol.

The rest of this document describes (1) the chat server protocol and sample code to play with its features, (2) goal and design constraints for your chat client programs, (3) hints and suggestions, and (4) submission instructions.

2. Chat server protocol

The chat server implements an unreliable channel much like paths in a datagram network like the Internet. The server is running both on <plum.cs.umass.edu, 8888> and <pear.cs.umass.edu, 8888> waiting for UDP datagrams. The chat server can do one of exactly three things with the datagrams it receives:

  1. process control commands and return response messages;
  2. relay messages to another client;
  3. echo messages (the default option).

You can use the command-line utility netcat (or the trivial client UDPClient.java) to play and familiarize yourself with the chat server protocol. Using either of those two (e.g., nc -u server port) try out the following interactions; the first line is what you type on the standard input prompt and the second is the response sent by the server. The numbers 1 and 2 refer to the two terminals respectively, and the background colors distinguish between sent and received messages.

By default, the server will simply echo messages back to the sender.

1
Hello there
Hello there

The control command NAME (case-sensitive) allows you to assign an arbitrary alphanumeric word without white spaces as your chat handle. All success responses will begin with OK and will be exactly one line long. The server will ignore all leading and trailing whitespaces while trying to interpret messages as control commands.

1
NAME Superman
OK Hello Superman

Use the NAME command similarly on the other terminal.

 
NAME Batwoman
OK Hello Batwoman

At this point, the LIST control command should show you the list of registered participants in the chat room like below.

1,2
LIST
OK LIST = Batwoman/127.0.0.1:51970 Superman/127.0.0.1:61496

The CONN control command allows a client to start talking to another client as shown below. From this point onward, the chat server will relay all messages from Superman (terminal 1) to Batwoman (terminal 2). Note that CONN sets up a unidirection relay, i.e., messages sent by Batwoman will not be relayed to Superman (unless Batwoman sends a CONN Superman control command to the server).

1
CONN Batwoman
OK Relaying to Batwoman at /127.0.0.1:51970

Note that instead of CONN Superman, the server also allows you to specify an IP: port combination as below. This will be handy in case someone else hijacks your NAME by announcing it as theirs. The NAME command is provided for the convenience of not having to type IP addresses and port numbers. Make sure to pick two names that are unlikely to be used by anyone else in order to prevent inadvertent connection hijacking.

1
CONN 127.0.0.1:51970
OK Relaying to Batwoman at /127.0.0.1:51970

At this point, Superman can start chatting with Batwoman using the relay as set up above.

1   2
Hello Batwoman, how goes?    
    Hello Batwoman, how goes?

Sending a period '.' (without the quotes) on a line by itself acts as a control command to stop the relaying set up above.

1
.
OK Not relaying

Note that when the server is in relay mode, it will not echo messages back to the sender and will only relay them to the relay destination. It will also not accept any control messages like NAME or CONN above and simply treat them as data messages to be relayed to the relay destination. You have to use the '.' command to get back to the default control/echo mode.

The QUIT control command clears all state created by clients using control commands like NAME, CONN, etc. Please use QUIT gracefully before exiting. Otherwise, a garbage collector will delete all client state after about 30 minutes of inactivity, but if too many users all use the server at the same time, the server could run out of memory and clear client state earlier.

1
QUIT
OK Bye

The big catch is that the server uses only UDP and might drop packets. Control and echo messages as above might get dropped if you have a poor network connection, but relay messages can additionally get dropped because the server is designed to be "mean". The relay channel has LOSS, DELAY, DELAY_DEV_RATIO, and CORRUPTION parameters that specify how often the channel can lose, delay, or corrupt packets. You can change these for testing your client under different (potentially harsh) conditions as below. All control commands to modify the channel parameters should be sent in the format CHNL <parameter_name> <parameter_value> as shown below.

1
CHNL LOSS 0.2
OK CHNL LOSS 0.2

You can also set multiple parameters as below.

1
CHNL LOSS 0.2 DELAY 0.2 CORRUPTION 0.01
OK CHNL LOSS 0.3 DELAY 0.2 CORRUPTION 0.01

The LOSS parameter indicates the probability of a packet being lost. The DELAY parameter is the delay in seconds. The CORRUPTION parameter is the probability of exactly one byte getting corrupted, i.e., randomly switched to a different byte, in each 100-byte block in the datagram. The DELAY_DEV_RATIO specifies the ratio of the delay deviation and the average delay, e.g., a delay of 0.2 with a delay_dev_ratio of 0.5 means the delay is 200 milliseconds plus/minus 0-to-100 milliseconds.

The default values of LOSS, DELAY, DELAY_DEV_RATIO, and CORRUPTION are respectively 0.1, 0.1, 1.0, and 0.01. You can display the current channel parameters using the CHNL PARAMS control command.

1
CHNL PARAMS
OK CHNL LOSS 0.1 DELAY 0.1 DELAY_DEV_RATIO 1.0 CORRUPTION 0.01

3. Goal and design constraints

Your goal is to implement a client program that ensures reliable, in-order delivery of data to another running instance of the program through the chat server as fast as possible. For example, a transcript of a longer conversation may look like this:

1   2
Hello Batwoman
How are you?
Here, let me cut-paste the transcript of the Gettysburg address
Four score and seven years ago...
...
...
...
Did you get it?
 

 

   

Hello Batwoman
How are you?
Here, let me cut-paste the transcript of the Gettysburg address
Four score and seven years ago...
...
...
...

Did you get it?

Your client should also be able to take input data from a file if one is specified as a command-line argument as detailed in "Submission instructions" below. We will only test your clients for unidirectional transfer, so it is up to you to decide whether the two clients are identical (like in TCP) or one is explicitly a sender and the other a receiver (like in Go-Back-N or Selective-Repeat protocols we have seen in class).

3.1 Design constraints

Your code must be completely your own. Additionally,

  1. You can only use UDP.
  2. You can only send/receive message to/from the chat server.
  3. The server will truncate any messages longer than 2048 bytes.
  4. You can use a pipelined protocol with a window size of at most 16 segments. The server will drop further messages from a client after buffering that many segments.
  5. You can not rely on CHNL commands in your submitted client for obvious reasons. They are only meant for you to test your code under various conditions. We will disable all CHNL commands (including CHNL PARAMS) while evaluating your client.

You are free to design your own header format inside UDP messages. In this assignment, UDP is like IP and you reliable transport protocol's headers and payload will be encapsulated within a UDP datagram. You can use checksums, sequence numbers, timers, and any other mechanisms you deem needed and implement them in any language of your choice.

4. Hints and suggestions

  1. You can run the chat server ChannelEmulator.java yourself on a local machine in case our servers are down. You are also welcome to browse through the code if you are curious, but you really should not have to.
  2. Comment your code helpfully for your own benefit as well as to make it readable for us.
  3. Don't forget that the channel can reorder packets as the delays have some variability.
  4. Don't forget to quite the relay mode by issuing "." in order to be able to send control commands, otherwise control commands will simply continue to get relayed.
  5. Don't forget that the server only mangles relay messages, but occasionally some control and echo messages might also get dropped as you are using UDP after all. You must wait for an OK message to ascertain that your control message was processed by the server successfully.
  6. First get the protocol to work correctly (part A), then you can optimize performance all you want (part B). You may want to start with a stop-and-wait protocol as that is likely easier.
  7. Self-testing tips coming here soon: Refer piazza PA2 FAQ and tips.

5. Submission instructions

  1. You must submit your client program named as ChatClient.<appropriate-extension>. We will test your client as follows. Suppose your main classes are ChatClientSender and ChatClientReceiver in java. Running the receiver followed by the sender on two different terminals (on possibly different machines) as follows should result in transferring the contents of the local file filename1 correctly to the remote end and stored there as filename2.

    java ChatClientSender -s server_name -p port_number -t filename1 filename2
    java ChatClientReceiver -s server_name -p port_number

    The client must support command-line arguments as above to specify the name and port number of the chat server and the input and output files. The default values of these paramters should be set to one of the server/port combinations above, standard input, and standard output respectively.
  2. You can use any programming language of your choice. For python for example, replace "java" above with python and suffix the class file names with the .py extension in the command-line format above.
  3. Zip all the above mentioned items into a *SINGLE* zip file and submit. The zip file must be of the form <lastname>-pa2.<extension>