Assignment 2: Octoput Transfer Protocol (40 marks)
Due: Friday, March 2, 2018 (4:00pm)Learning Objectives
The purpose of this assignment is to learn about network applications, transport-layer protocols, and reliable data transfer. In particular, you will write a C or C++ program that implements a simple file transfer protocol using UDP instead of TCP. Along the way, you will refine your skills at reading and interpreting protocol specifications, such as those in an RFC.
Background
Inspired by this famous cartoon, Ollie the Octopus was the first in his family to obtain an Internet account. Since he now loves the Internet so much, he has recently set up a home network so that he can share his travel photos, blog posts, and data files with other family members, including his parents Odie and Omie, and his siblings Oddie and Ozzie. Yes, they are triplets, but Ollie is slightly older than his two sisters.
There are two important things to know about Ollie. First, he is a bit of techno-geek, and prefers building his very own file transfer protocol (Octoput), rather than using FTP, TFTP, SMTP, or the Web. Second, Ollie seems particularly obsessed with the number eight, though we are not sure why.

Technical Requirements
In this assignment, you will design and implement a simple file transfer application using UDP, and test it on a network of your own choosing. Your application can be either client-server or peer-to-peer (your choice), and it can be either pull-based or push-based (your choice).
Your network application will use UDP (i.e., datagram sockets) for its underlying transport-layer protocol. With TCP, reliable data transfer is provided "automatically" by the transport layer, but there is a lot of extra overhead involved in the communication (e.g., handshaking, ACKs, timers, retransmission, flow control, congestion control, checksums), not all of which are needed for our purposes. With UDP, the transport-layer endpoints are simpler, but you may need to add a few reliable data transfer mechanisms (e.g., timeouts, retransmissions) in order to make Octoput work properly.
In Octoput, everything is about symmetry, and the number eight. The default unit of transfer is the octoblock, which is 8888 bytes in size. Data files that are larger than this require multiple octoblocks. At most one octoblock can be in transit between a sender and a receiver at a time. That is, an entire octoblock must be delivered and acknowledged successfully before one can start transmitting the next octoblock. The octoblock in turn is made up of eight octolegs, each of which is 1111 bytes in size. These octolegs can be sent at any time, and in any order, but must indicate which piece they are within the octoblock, so that the receiver can put the octoblock back together at the other end. This is done using an 8-bit (one byte) field, such as '00100000' to indicate the third octoleg in an octoblock.
Ollie has defined some aspects of Octoput somewhat recursively. For example, if a data file is not a perfect integer multiple of 8888 bytes, then one first sends as many full octoblocks as possible, and then sends at most one partial octoblock for the remaining data. This partial octoblock should have eight equally-sized pieces, if at all possible. If not possible, then use the largest possible size that gives equally-sized pieces, and a wee bit of leftover data (between 1 and 7 bytes). For the leftover data, if any, one uses a tiny octoblock (the minimum legal size is 8 bytes), which has eight octolegs of one byte each. If necessary, some of these tiny octolegs carry pad bytes (the blank space character), which will be removed by the receiver based on knowledge of the actual data file size.
Note that the sender and receiver both need to know the size of the original data file being transferred. Based on this, they can both use the same algorithm to determine what to expect in terms of number, size, and sequence of octoblocks. That is, the protocol is deterministic in this respect, though the sequencing of the octoleg transmissions within a given octoblock is entirely flexible.
It is up to you to determine what control information goes into your UDP packets, and where. For example, you will need the octoleg flag for sure, and some way of conveying file size information from sender to receiver.
One of your main tasks will be to provide reliable delivery of octoblocks using UDP. For this, you might need ACKs, timers, retransmissions, and such. Where to put these, and how to implement them, is up to you.
Grading Rubric
The grading scheme for the assignment is as follows:
- 16 marks for the design and implementation of a UDP-based solution to this problem. Your implementation should include proper use of UDP socket programming in C or C++, and reasonably commented code. Make sure that you can transfer small ASCII text files, such as these: 736-byte test file, 739-byte test file, 1 KB test file, 2 KB test file, 4 KB test file, 8 KB test file, and 8888-byte test file. Test your solution using a real network of your own choosing (wired or wireless). There is no need to test beneath the ocean.
- 8 marks for extending your UDP-based solution to this problem so that it can successfully handle larger files, such as this 32 KB ASCII test file. Think carefully about the design of a non-blocking (i.e., multi-threaded or multi-process) implementation that handles concurrency well. Test your solution either on a single machine using the loopback interface, or using a real network of your own choosing.
- 6 marks for a clear and concise user manual (at most 1 page) that describes how to compile, configure, and use your application. Make sure to indicate (and justify) your design choice (i.e., push-based or pull-based), and describe any special features that are supported. Please include a paragraph or two about your use of UDP as a transport-layer protocol, and the implications of this choice (e.g., size/complexity of code, scalability, range of parameters supported, portability of code across different networks). Last but not least, describe where and how your testing was done (e.g., home, university, office), what works, and what does not. Be honest!
- 10 marks for a suitable demonstration of your Octoput protocol to your TA in your tutorial section, or to your professor at a mutually convenient time. All demos will be done during the week of March 12 (after the midterm).
Bonus (4 marks): Extend your solution as necessary so that it can successfully handle a large 256 KB ASCII test file.
When you are finished, please submit your assignment solution to your TA via D2L. Your submission should include your source code and user manual documentation.
Tips
- This assignment is extremely challenging, so please get started early!
- Looking at Carey's "word server" example might provide a useful starting point for understanding how UDP data transfers work.
- You can write a TCP-based version as well if you want. It might provide some insights and help you with debugging. Maybe.
- On a single machine, you can do your initial testing using the loopback interface.
- Once you are testing on a real network interface, you may find Wireshark particularly useful to look at the network packets being sent and received by your application (i.e., ports, size, data content).
- When testing some parts of the protocol, you may want to insert some artificial timing delays between the transmissions of octolegs, or even randomize the order in which octolegs are transmitted.
- To test timeouts and retransmissions in your protocol, it might be helpful to have a receiver that randomly discards the occasional octoleg on purpose.
- Stick with plain-text ASCII files for your testing. Start small, and then work upwards to larger files for your final experiments.
- Work with very small files (less than 1 KB) to start with, so that you can put verbose debugging in to test the functionality of your protocol. Once these are working right, you can scale up to larger files (4 KB or more) to tackle any new challenges that arise.