CS 372 Project 2
1
CS/ECE 372 Project 2 – Reliable Data Transmission (RDT)
Due: Sunday, Nov 7th, 11:59 pm via Canvas
Introduction
In this project you will code part of a simulation in order to understand the principles and practice of
Reliable Data Transmission (RDT). You will complete the RDTLayer class that allows the transfer of
string data through an unreliable channel in a simulated send-receive environment.
Code for the UnreliableChannel class, the Segment class (data or ack packets**), and also the
calling main function, is provided. You will need to complete the implementation for the RDTLayer
class. Note that there is an instance of RDTLayer for both sender and receiver (see rdt_main.py).
The RDTLayer must therefore be able to send and receive data and ACK segments.
Your code should be able to simulate many of the features discussed in lecture and in your textbook for
RDT and TCP. Note that we will not be using actual TCP headers or bytes. This is more high-level than
that, but the principles are the same.
RDTLayer
The RDTLayer class needs to provide reliable transport no matter how bad the unreliable channel is at
delivering packets. And it is bad! The UnreliableChannel class may do any of the following:
• Deliver packets out-of-order (data or ack packets)
• Delay packets by several iterations (data or ack packets)
• Drop packets (data or ack packets)
• Experience errors in transmission (failed checksum – data packets only)
• Various combinations of the above
**The words ‘segment’ and ‘packet’ are frequently used interchangeably with TCP communications.
The RDTLayer class must handle all of these and deliver the data correctly and as efficiently as
possible. In this project, you must finish the implementation of the RDTLayer class. To help build your
RDTLayer implementation, the UnreliableChannel class takes flags that can turn on/off the
different types of unreliability. It is recommended that you use those flags, starting with completely
2
reliable channels, get that working, and go from there, enabling each of the unreliable features in turn;
these flags are marked with comments for when to toggle them on or off depending on the step you are
working on! These flags can be seen in rdt_main.py.
Note that the Segment class already has methods for calculating and checking the checksum. It also
has methods for saving a ‘timestamp’ (iteration count). We will be using iteration count instead of time,
because the simulation executes much too quickly to use actual time.
Your final RDTLayer implementation must:
• Run successfully with the original provided UnreliableChannel and Segment classes
• Deliver all of the data with no errors
• Succeed even with all of the unreliable features enabled
• Send multiple segments at a time (pipeline)
• Utilize a flow-control ‘window’
• Utilize cumulative ack
• Utilize selective retransmit
• Include segment ‘timeouts’ (use iteration count, not actual time)
• Abide by the payload size constant provided in the RDTLayer class
• Abide by the flow-control window size constant provided in the RDTLayer class
*Hints:
1. In rdt_main.py, you will see two different length texts to send through the RDTLayer.
Start with the smaller one, then try the larger one.
2. You can add more helper functions in rdt_layer.py.
Detailed Instructions:
Your implementation of RDTLayer will be done in incremental steps, which are outlined with Steps 0-
5 folders in the Project2.zip file. Within rdt_layer.py there are block comments indicating where
changes need to be made for each of the steps.
*Note*
The TAs will be grading each of your steps. To ensure that you maintain each step,
make sure you COPY and NOT MOVE your rdt_layer.py from one step folder to
the next. For example, once you complete Step1, COPY the rdt_layer.py in Step1
folder into the Step2 folder.
3
Step 0: Sending ONE packet of ONE-character length
Step 0 is already implemented for you. Please CAREFULLY READ ALL COMMENTS to understand
the program flow. You can test this by running “python3 rdt_main.py” within the Step0/
directory on the school server. The RDTLayer class contains member variables DATA_LENGTH and
FLOW_CONTROL_WIN_SIZE that reflect that we currently are sending one character at a time and
waiting for that ACK before sending another character.
Example screenshot for Step 0:
*Note: this transmission is NOT complete since we stop it after 1000 iterations
Step 1: Sending ONE packet of Multi-character length
In Step 1, we will be changing the DATA_LENGTH and FLOW_CONTROL_WIN_SIZE within the
RDT_Layer to begin sending multi-character packets (i.e., each packet contains 4 characters instead
of 1). To accomplish this, you will need to modify the variables that control the data and window size, as
well as rdt_send() and rdt_recv(). Make sure you read the block comments in the code! What
do you expect to see with the output such as countAckPackets when you increase your data size?
Example screenshot after completing Step 1:
4
Step 2: Sending Multiple packets of Multi-character length
In Step 2, we will begin sending multiple packets at a time; we will increase our window size. To
achieve this, you will need to modify several parts within rdt_send() as well as the window size
variable to be able to pipeline our data rather than sending one packet and waiting for its ACK.
Example screenshot after completing Step 2:
5
Step 3: Handle outOfOrder Errors
Now our program is able to send multiple packets of multi-characters length. Step 3 is where we begin
to handle the errors that come from real-world scenarios. There is a dictionary member in RDTLayer
for you to utilize in this step. The functions you need to implement and/or edit are:
– deliver_data() – Using the dictionary of received data, deliver the data in the correct order
by ack number
– getCumAck() – calculate and return the cumulative ack that is stored in dictReceived
– rdt_recv() – instead of appending payload (data) to dataReceived member, add segment
to dictReceived dictionary
– rdt_recv() – modify acknum that is stored to get cumulative ack (See “Hint” in the
comments)
Be sure to check the unreliable flags in main, you may need to toggle one of them in this step 🙂
Example screenshot after completing Step 3:
6
Step 4: Handle dropPackets and delayPackets Errors
In Step 4, we implement timeouts. Adding to the reliability of this program, for example, if a segment
was sent in iteration 5, if we don’t receive it after a few iterations (i.e., by the end of iteration 7), we
need to know that segment timed out and we should resend it. To accomplish this, you will set a new
variable in RDTLayer and utilize members currentIteration and countSegmentTimouts.
The functions you should edit are:
– manageSegmentTimeouts() – calculate/detect any timeouts of any of the segments
– rdt_send() – set the current segments starting iteration
Be sure to check the unreliable flags in main, you may need to toggle some of them in this step 🙂
Example screenshot after Completing Step 4:
7
Step 5: Handle dataErrors Errors
The final Step handles any dataErrors by checking if the current segments checkCheckSum()
function returns false. If so, you will need to increment the RDTLayer countChecksumErrors
member by 1. You will write this code within the rdt_recv() function.
Be sure to check the unreliable flags in main, you may need to toggle one of them in this step 🙂
Example screenshot after completing Step 5:
8
Extra Credit Step: Efficiently run with less timouts reported
Are you able to reduce the number of timeouts to transmit the same data without changing the data
length in each packet and the window size? Within this step, you are asked to remove corresponding
sent packets in the sent dictionary once you receive an ACK with larger value. The functions you should
edit are:
– removeSentSegmentsToAndIncluding() – Remove keys up to and including the
provided one
– rdt_recv() – call the function above once an ACK is received
Example screenshot after completing Extra Credit Step:
9
What to turn in
1. In the pdf:
a. Include instructions on how to run your programs. Are they python3?
b. Take screenshots of your running code for each of the steps, labeling which screenshot
is for what step.
c. Include comments / questions (optional)
2. Make a zip file that contains Step0-StepEC folders (as the provided zip file). In your code
(rdt_main.py, rdt_layer.py, unreliable.py) listings:
a. Include sources you used (web pages, tutorials, books, etc)
b. Comment your code