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:
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.
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:
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 |
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 |
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).
Your code must be completely your own. Additionally,
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.
filename1
correctly to the remote end and stored there as filename2
.