This is the code from the 7th plenum lecture.

sender/receiver: UDP file transfer with retransmission timeouts and packet sequence numbers.

The *_simple variants are just the old hello world / old file transfer programs without retransmission timeouts.

To generate files to transfer:
dd if=/dev/urandom of=<your_best_filename.bin> bs=1024 count=100

* If you change the file transfer size in the code, you will also have to change the count in the dd cmdline.

-----------------------------------
I recommend a reflection excersise.
-----------------------------------

You should run the _simple variants (compile them yourself with GCC).
Run the code on local loopback interface (127.0.0.1, change the IP addresses in the files).
You must make sure the port numbers are unique (the same port number cannot be used twice on the same interface).
I don't prepare this for you because you may want to run the code between two machines, and you should get some feel for working with the code.

Next, try to study the _simple code and answer the questions below. The answers are given after. There is no shame in looking at the answers! Spend a few minutes on each and see how you do.


Q.1) Consider the simple variant of the file transfer code. What are the actual problems with respect to packet loss?

ANSWER
hen the sender sends a packet, it can get lost because we use UDP. So the receiver can wait forever if a single packet is lost.

Sender                          Receiver
---------------------------------------------
Read file chunk
             Send file chunk
             ------------->
                             Store file chunk
Read next file chunk
             Send file chunk
             ----XXXXXX Packet loss
                             Wait for file chunk forever

Q.2) What can we do to solve this? (Note: there may be more than one answer here, I will go the path laid out in the plenum lecture).

ANSWER
We can solve this by having the receiver confirm that it has received the last file chunk (an acknowledgement packet, or ACK).

Sender                          Receiver
---------------------------------------------
Read file chunk
             Send file chunk
             ------------->
Wait for ACK                Store file chunk
                 Send ACK
             <-------------
Read next file chunk
             Send file chunk
             ------------->
Wait for ACK                Store file chunk
                 Send ACK
             <-------------

Q.3) With our acknowledgement approach, are there any new problems that can arise?

ANSWER
The next problem that arises, is that the ACK can get lost.

Sender                          Receiver
---------------------------------------------
Read file chunk
             Send file chunk
             ------------->
Wait for ACK                Store file chunk
                 Send ACK
             <-------------
Read next file chunk
             Send file chunk
             ------------->
Wait for ACK                Store file chunk
                 Send ACK
        Packet loss XXX----
Wait for ACK forever

Q.4) How can we solve the "lost ACK" problem"?

ANSWER
We let the sender use a retransmission timeout using select() (see man select).

Sender                              Receiver
------------------------------------------------
Read file chunk
               Send file chunk
                ------------->
Wait for ACK with timeout       Store file chunk
                 Send ACK
        Packet loss XXX----
ACK Timeout
Send file chunk again
               Send file chunk
                ------------->
Wait for ACK with timeout       Store file chunk
                 Send ACK
                <-------------
Read file chunk
               Send file chunk
                ------------->
Wait for ACK with timeout       Store file chunk
                 Send ACK
                <-------------

Q.5) In the case of a lost ACK, even though we retransmit the last packet, what happens to the received file if an ACK gets lost?

ANSWER
The same chunk is sent twice, so the received file will be corrupted (not the same as the sender).

Sender                              Receiver
------------------------------------------------
Read file chunk 0
               Send file chunk 0
                ------------->
Wait for ACK with timeout       Store file chunk 0
                 Send ACK
        Packet loss XXX----
ACK Timeout
Send file chunk again
               Send file chunk 0
                ------------->
Wait for ACK with timeout       Store file chunk 0 <<<<<<< The same file chunk is stored twice!

Q.6) What can we do?

ANSWER
Use a sequence number. We add a sequence number to each file chunk such that the receiver can select which ones to store, and which ones to not. It always ACKs to keep the sender sending.

Sender                              Receiver
------------------------------------------------
Read file chunk 0
               Send file chunk 0
                ------------->
Wait for ACK with timeout       Store file chunk 0
                 Send ACK
        Packet loss XXX----
ACK Timeout
Send file chunk again
               Send file chunk 0
                ------------->
Wait for ACK with timeout       !! Got sequence number 0, expecting 1! Ignoring to write.
                 Send ACK
                <-------------
Read file chunk 1
               Send file chunk 1
                ------------->
Wait for ACK with timeout       Store file chunk 1
                 Send ACK
                <-------------


CHALLENGE QUESTION! Worthy of a prize.

Consider the timeout mechanism on the sender.
There is a harmless subtlety here, but a subtlety nonetheless.
Something in the possible flow of events that is hard to picture.
What is it?

Good luck!
