The purpose of this assignment is to implement a reliable File Transfer Protocol (FTP) service over UDP. This project will help you understand some of the important issues in implementing reliable data transfer protocols. You will write the reliable FTP client and server programs based on an Alternating Bit Protocol (ABP) that will communicate with a specially designated server.
In this project, you are to implement a reliable FTP client program written in either Python, C, or C++, or Java. We are establishing our own protocol for performing a file transfer from a server to a client. The reliable FTP protocol (RFP) adopted here uses the Alternating Bit Protocol (see Section 3.4 of your text) to ensure that the packets and received reliably. This will be a highly constrained version of FTP where there are no FTP commands, and you don’t even get to choose what file to transfer. In this implementation, you will make a connection to the FTP server, and then begin the file transfer as prescribed below.
Our protocol will be encapsulated entirely within the payload of a UDP packet. As you know, UDP provides “best effort” in transferring data, yet is not considered reliable. In this assignment, we will construct the UDP payload to include extra information which we can use to establish a reliable transfer channel. To make this more challenging, packets between the client/server may be mutilated or dropped altogether. You are tasked to compensate for problems in transmission, and provide a reliable and timely transfer service between the two hosts.
The UDP payload will contain its own encapsulated data structure consisting of a header and data fields. A packet using our protocol will look like this:
The four fields of the “RFP” protocol are:
- SEQUENCE: This is the sequence number of the packet, and can legally assume either of the two values: “0000” or “0001”.
- CHECKSUM: This is a 4-digit ASCII number that is the byte-by-byte sum, modulo-10000, of all data in the payload including the header SEQUENCE and header CONTROL.
- CONTROL: Used by the server to indicate Transfer in Progress “0000” or All Done “0001”. The client should set this field to “0000”. “0002” is reserved for future use.
- DATA: Used by the server to send part of the data file it is transferring
All of the above fields are human readable, and easily discerned with a tool like Wireshark. If this were a real reliable transport protocol, we would do something like TCP with a three-phase handshake to establish the channel. In this instance, we shall do something simple. We will establish a “channel” somewhat as we did with the Quote of the Day protocol; however, here, the server will respond with a unique UDP port for you to use for your file transfer:
- Open a TCP connection to moby.ece.vt.edu over port 21000
- Send the word “normal” to the server over this port.
- The server will respond with a number formed in an ASCII string. This is the UDP port that you shall use in the file transfer session.
- Close the TCP connection.
Once you have been assigned a UDP port, you are ready to start the file transfer after you open the socket.
To initiate the file transfer, the client should send an ACK1 packet (sequence number = “0001”, control = “0000”, a computed checksum, and zero bytes of data. As stated above, the checksum is the character-by-character ordinal sum over the entire packet (excluding the checksum field). For the ACK1 packet, checksum = “0”+”0”+“0”+”1”+“0”+”0”+“0”+”0” = ASCII 48 + 48 + 48 + 49 +48 + 48 + 48 + 48 = 385. The 4-digit modulo-10000 ASCII decimal equivalent of this checksum is “0385.”
The server will then start sequentially sending the file data, starting with a packet with Sequence Number 0. Abide by the Alternating Bit Protocol to transfer the contents of the file. When the server has completed the file transfer, it will send a final packet with no data with the control field set to “0001.” You must ACK this packet. Then you can close your UDP session and save the output file.
Since the file will be larger than a single packet, the server will segment the file into chunks that will fit within packets. The client will need to reassemble these and put them in a file called reliable.txt.
The server will have the ability to corrupt data and drop packets, both incoming and outgoing, as what might happen in a normal network. You will need to recover from these errors. Refer to Figure 3.16 of your text which illustrates various error recovery sequences. When your client detects an error condition, print a message describing it.
It is the burden of the client to make sure that each received packet is valid. If the packet is valid, the client must send the proper ACK to the server. If the packet is not valid, it must be discarded, and you must rely upon a new copy of the packet from the server. The packet timeout period is fixed at 200ms.
For debugging, it may be useful to verify the operation of your code without the presence of errors. You can disable packet corruption by sending the word “debug” instead of “normal” in your initial TCP handshake. Note that the underlying transfer protocol is UDP, and hence it itself is subject to packet loss in the network.
Be sure to use Wireshark to assist in the debugging.
A NORMAL MODE run of the program may take 2-3 minutes to run.
Here (TheTimeMachine.txt) is a clean copy of the file transferred by the server.