Assignment 6: UDP file delivery

Due date: 5:00pm, Friday, November 15. Value: 120 pts.

About TFTP

TFTP (for Trivial File Transfer Protocol) is designed as an extremely simple protocol for delivering a file across a network. It is particularly useful for low-memory devices. Because TCP is quite complex and thus unsuitable for such devices, TFTP is built on top of UDP, which of course means that message delivery is not assured.

TFTP packets come in four varieties: File Request, Data, Acknowledgement, and Error. (There is also a Write Request packet for saving files, but we'll disregard this category.) Communication proceeds as follows:

  1. The TFTP server listens on the well-known UDP port number 69. (Our server will use 6900.)

  2. A TFTP client will reserve an arbitrary UDP port P on its computer and send a File Request packet to the TFTP server.

  3. On receiving the File Request packet, the server will select another arbitrary UDP port Q on its computer. From now on, all communication in this transaction will occur between port Q on the server and port P on the client. (This port selection process allows a client to simultaneously request multiple files.)

  4. In response to the File Request packet, the server sends a Data packet with the block number 1, containing the file's first 512 bytes.

  5. Upon receiving the Data packet, the client sends an Acknowledgement packet for block number 1.

  6. Of course, the Data packet may not reach the client, in which case the client would of course not send Acknowledgement; so the server, who is listening for Acknowledgement, will have some timeout whereupon it re-sends the Data packet. It should keep trying to re-send until it receives an Acknowledgement. Of course, this means that the client may end up receiving the same Data packet multiple times, if its Acknowledgement packets are lost or delayed.

  7. Upon receiving Acknowledgement for block 1, the server sends a Data packet with block number 2, with the file's next 512 bytes. Upon receipt, the client sends an Acknowledgement packet for block 2.

  8. The server and client continue such communication until the server reaches the end of the file. When the server has less than 512 bytes left, it sends only those bytes; the client knows that a Data packet of fewer than 512 bytes means that the server has reached the file's end. (If the file's length is a multiple of 512, there is a Data packet of 0 bytes.)

  9. After the server receives Acknowledgement for this last Data packet, it knows that communication is complete and thus stops sending packets. After the client acknowledges to the last Data packet (with less than 512 bytes), it knows that communication has ceased and sends no further packets; however, to be courteous, it should still look for more packets from the server, since the Acknowledgement packet may not make it, in which case the server will re-send the Data packet which a courteous client should be ready to acknowledge.

Throughout all of this, either the server or the client could encounter a problem: Two possibilities are that one receives a malformed packet sent by the other, or the server can no longer read the file. In that case, whoever encounters the error sends an Error packet, which signals that the transaction ends. Of course, the Error packet may not reach the other host, so a host should be prepared to simply end the transaction prematurely.

(By the way, there is a small but important incompatibility between the TFTP definition and the implementation we'll be working with. In the formal TFTP, each Data and Acknowledgement packet dedicates just two bytes to the block ID, but the distributed code uses four bytes for each block ID.)

Your job

The provided code implements a TFTP client and server. You will not need to modify any files but the first one.

TftpServer This is the file that you will modify. It implements a simple in-order server implementation, as specified by TFTP.
TftpMain Contains the main method, which kicks off the server, listening for connections, then kicks off a client. Once the client requests a file, it opens the file, creates a TftpServer object, and executes its run method.
TftpClient Implements a TFTP client, enhanced to deal with out-of-order block delivery.
UdpModeledConnection Substitutes for a UDP connection with support for some artificial network modeling, introducing dropped packets and random network delays, as described in “Network model” below.
TftpPacket Provides helper methods for packing and unpacking information in a TFTP packet, according to TFTP specification.
TftpException An exception that is thrown by TftpPacket when it finds that the packet is malformed, or internally by TftpServer and TftpClient when they encounter other errors that should lead to an Error packet being sent.
words.txt A 22.2K file for testing file transfer. You can change the file or its path by changing the FILE_NAME constant in TftpClient; it currently assumes that you are executing in an Eclipse project with the file listed in the src subdirectory.

Your job is to enhance TftpServer to deliver a file more efficiently and to write a report on your findings (in, Word, or PDF format). I expect your report will discuss several methods you tried, including how each method works, what your reasoning was behind trying the method, and how well it performs; the report would conclude with a recommendation. I expect that a good report could be executed within two single-spaced pages.

It may be tempting to judge performance purely by the amount of time taken to deliver the file. But you could also consider the total number of packets delivered or the average number of packets delivered per second, since these measure how hard your protocol is on a network.

You should submit two files: Your report (, Word, or PDF format) and the implementation of TftpServer that matches with your concluding recommendation.

Network model

If we were to execute the server and client on different computers in our Linux network, we would find that basically all packets reach their destination extremely quickly, with little variation. This would be uninteresting, so instead we work with a simulated network implemented in UdpModeledConnection. There are two pieces to the simulation: Randomized times for packets to be delivered between server and client, and probability that a packet would be dropped.

To compute how much to delay a packet, we use a normal distribution (illustrated at right) with a mean μ of 50 ms and a standard deviation σ of 10 ms. Of course, this means that there's a 68.2% chance that the packet is delivered between 40 and 60 ms, but a 2.2% chance that it takes less than 30 ms, and another 2.2% chance that it takes more than 70 ms.

To determine the probability that a packet should be dropped, the simulator keeps track of how many packets have been delivered over the previous 200 ms. If n is the number of such packets, the packet-drop probability is computed as n / 40 + 0.1 — or 1 (i.e., 100%) if this quantity exceeds 1. Consequently, all packets will be dropped if the program attempts to send 36 or more packets within 200 ms; but if you deliver a packet just once every 50 ms, then n would be 4, so the drop probability would be 0.2.