The goal of this assignment is to implement a Reliable Data Transfer (RDT) protocol, which could be used to reliably transfer a text file from one host to another across an unreliable network. The protocol should be able to handle network errors (packet loss), packet reordering, and duplicate packets. For simplicity, your protocol is unidirectional, i.e., data will flow in one direction (from the sender to the receiver) and the acknowledgements (ACKs) in the opposite direction. To implement this protocol, you will write two programs: a sender and a receiver, with the specifications given below. To test your implementation, you will write a third program that will emulate an unreliable network link.
When the sender needs to send packets to the receiver, it sends them to the network emulator instead of sending them directly to the receiver. The network emulator then forwards the received packets to the receiver. However, it may randomly discard received packets. The same scenario happens when the receiver sends ACKs to the sender.
All packets exchanged between the sender and the receiver should have the following structure:
|integer type;||// 0: ACK, 1: Data, 2: EOT|
|integer seqnum;||// sequence number of the packet|
|integer length;||// Length of the String variable ‘data’|
|String data;||// String with Max Length 500|
The type field indicates the type of the packet. It is set to 0 if it is an ACK, 1 if it is a data packet, 2 if it is an end-of-transmission (EOT) packet (see the definition and use of an end-of-transmission packet below). For data packets, seqnum is sequence number of the packet. The sequence number of the first packet should be zero. For ACK packets, seqnum is the sequence number of the packet being acknowledged. The length field specifies the number of characters carried in the data field. It should be in the range of 0 to 500. For ACK packets, length should be set to zero.
Sender Program (sender)
You should implement a sender program, named sender. Its command line input includes the following:
<host address of the network emulator>, <UDP port number used by the emulator to receive data from the sender>, <UDP port number used by the sender to receive ACKs from the emulator>, <timeout interval in units of millisecond>, and <name of the file to be transferred> in the given order.
Upon execution, the sender program should be able to read data from a text file (10KB to 15KB) and send it using the RDT protocol to the receiver via the network emulator. The RDT is pipelined. The window size should be set to N=30 packets so that the sender can pipeline the entire file. After all contents of the file have been transmitted successfully to the receiver (and corresponding ACKs have been received), the sender should send an EOT packet to the receiver. The EOT packet is in the same format as a regular data packet, except that its type field is set to 2 and its length is set to zero. The sender can close its connection and exit only after it has received ACKs for all data packets it has sent and received an EOT from the receiver. To keep the project simple, you can assume that the end-of-transmission packet never gets lost in the network.
In order to ensure reliable transmission and congestion control, your program should implement the RDT protocol as follows:
If the sender has a packet to send, it first checks to see if the window is full, that is, whether there are N outstanding, unacknowledged packets. If the window is not full (which should be the case here given the maximum size of the file, the size of the packet payload and the size of the window), the packet is sent. After all packets in the window are sent, the sender will start a countdown timer set to the inputted <timeout interval in units of millisecond>. When the sender receives an acknowledgement packet with seqnum n, the ACK will be taken to be a selective acknowledgement, indicating that the packet with sequence number n has been correctly received at the receiver. When a timeout occurs, the sender retransmits all non-ACKed packets and restarts the timer. These steps are repeated until there are no outstanding packets.
For both testing and grading purposes, your sender program should be able to generate two log files, named as seqnum.log, and ack.log. Whenever a packet is sent, its sequence number should be recorded in seqnum.log. The file ack.log should record the sequence numbers of all the ACK packets that the sender receives during the entire period of transmission. The format for these two log files is one number per line. You must follow this format to avoid losing marks.
Receiver Program (receiver)
You should implement the receiver program, named as receiver, on a UNIX system. Its command line input includes the following: <hostname for the network emulator>, <UDP port number used by the link emulator to receive ACKs from the receiver>, <UDP port number used by the receiver to receive data from the emulator>, and <name of the file into which the received data is written> in the given order.
When receiving packets sent by the sender via the network emulator, it should execute the following:
- acknowledge the packet; the seqnum of the ACK packet should be the same as the seqnum of the received packet;
- if the packet is a duplicate, it should be discarded; • if the packet is out-of-order, it should be buffered.
After the receiver has received all data packets and an EOT from the sender, it should send an EOT packet then exit. Make sure the file is saved before exiting!
The receiver program is also required to generate a log file, named as arrival.log. The file arrival.log should record the sequence numbers of all the data packets that the receiver receives during the entire period of transmission. The format for the log file is one number per line. You must follow the format to avoid losing marks.
Network Emulator (nEmulator)
When the link emulator receives a data packet from the sender, it will discard it with the specified probability. Otherwise, it forwards the packet to the receiver. The same behaviour applies to ACKs received from the receiver. EOT packet from the sender is never discarded. EOT packet from the receiver is never discarded.
To run nEmulator, you need to supply the following command line parameters in the given order:
- <emulator’s receiving UDP port number in the forward (sender) direction>,
- <receiver’s network address>,
- <receiver’s receiving UDP port number>,
- <emulator’s receiving UDP port number in the backward (receiver) direction>,
- <sender’s network address>,
- <sender’s receiving UDP port number>,
- <packet discard probability>,
- <verbose-mode> (Boolean: Set to 1, the network emulator will output its internal processing, one per line, e.g. receiving Packet seqnum /ACK seqnum, discarding Packet seqnum /ACK seqnum, forwarding Packet seqnum /ACK seqnum).
- You must run the programs in the CS Undergrad Environment
- Experiment with different sender time-out.
- Run nEmulator, receiver, and sender on three different machines in this order to obtain meaningful results.
- Make sure all log files and transferred file are saved before exiting. We cannot mark your programs if these files are missing.
- On the host host1: nEmulator 9991 host2 9994 9993 host3 9992 0.2 1
- On the host host2: receiver host1 9993 9994 <output File>
- On the host host3: sender host1 9991 9992 50 <input file>
Hand in Instructions
Submit all your files in a single compressed file (.zip, .tar etc.) to LEARN. The name of the file should be your Quest id.
You must hand in the following files / documents:
- Source code
- Makefile (if applicable): your code must compile and link cleanly by typing “make” or “gmake” (no need for make file if you use Python).
- README file: this file must contain instructions on how to run your program, which undergrad machines your program was built and tested on, and what version of make and compilers you are using.
Your implementation will be tested on the machines available in the undergrad environment.
Since there is no external documentation required for this assignment, you are expected to have a reasonable amount of internal code documentation (to help the markers read your code).
You will lose marks if your code is unreadable, sloppy, and inefficient.