Computer Networks - CSE 30264 - Programming Assignment 3


Total Points: 100 points
Goal: Program a Prototype of a FTP application
Assigned: September 26
Due: October 12 by the beginning of class October 31 by the beginning of class (Hard Deadline!)
Grouping: Completed by a group


Background

In this programing assignment, you will implement the client and server sides of a simple File Transfer Protocol (FTP) application. The file transfer itself will take place using TCP with the client determining the operation to be performed (requesting a particular file, uploading a file, deleting a file, creating a new directory, removing a directory, changing to a different directory, obtaining a directory listing, or closing the connection). The server should respond appropriately to the specific command. The specifics of the protocol are detailed in this handout. Note: please refer to appendix A for the port number assigned to your group for the assignment.

Protocol - Simple File Transfer

  1. Server opens port, and goes into “wait for connection” state.
  2. Client connects to the server on the appropriate port.
  3. Server goes into “wait for operation from client” state and waits for operation command from the client.
  4. Client goes into “prompt user for operation” state and prompts user for operation.
  5. Client passes operation (REQ: Request, UPL: Upload, LIS: List, MKD: Make Directory, RMD: Remove Directory, CHD: Change Directory, DEL: Delete, XIT: Exit) to server.
  6. Operation is executed as follows:
    1. REQ:
      Note: Please test REQ with the three test files (i.e., LargeFile.mp4, MediumFile.pdf, SmallFile.txt) discussed in the general notes.
      1. Client sends operation (REQ) to download a file from the server.
      2. Client sends the length of the file name (short int) followed by the file name (character string).
      3. Server decodes what it receives, and checks to see if the file exists in its local directory.
        1. If the file exists, server returns the size of the file to the client as a 32-bit int.
        2. If the file does not exist, server will return a negative 1 (32-bit int). After that, the server should return to the “wait for operation from client” state.
      4. Client receives 32-bit file length from server.
        1. Client should decode the 32-bit value.
          1. If the value is negative one, user should be informed that the file does not exist on the server. Client should return to “prompt user for operation” state.
          2. If the value is not a negative 1, save the value as the file size for later use.
      5. Server computes MD5 hash of the file and sends it to client as a 16-byte string.
        1. Client receives server's MD5 hash and saves it for future reference.
      6. Server sends the file to client.
        1. Client reads “file size” bytes from server.
        2. The client saves the file to disk as “file name”
        3. The client computes the MD5 hash of the received file.
          1. If client and server hashes are the same, inform user that the transfer was successful, and return to “prompt user for operation” state. The client displays throughput results for the transfer.
          2. If the hashes do not match, inform user that the transfer was unsuccessful, cleanup, and return to “prompt user for operation” state. Do not display the throughput.

    2. UPL:
      1. Client sends operation (UPL) to upload a local file to a server.
      2. Client sends the length of the file name which will be sent (short int) followed by the file name (character string). Note: you can create a local file called “upload.txt” with randomn strings to test the UPL operation.
      3. Server receives the above information, decodes file name size and file name, and acknowledges that it is ready to receive (it is up to you how to do the acknowledgment).
      4. Client replies with a 32-bit value which is the size of the file (in bytes).
      5. Server receives and decodes the 32 bit value.
        1. Server enters the loop to receive file
        2. Client sends file to server. Server reads “file size” bytes from client and saves them to disk as “filename”.
        3. Client computes MD5 hash of the file and sends it to server as a 16 byte string.
        4. Server receives the client's MD5 hash.
        5. The server computes throughput results for the transfer.
        6. The server computes the MD5 hash of the received file.
          1. If client and server hashes are the same, send the throughput results to the client. This information should be used by the client to inform user that the transfer was successful, display throughput information for the transfer, and cause the client to return to “prompt user for operation” state.
          2. If the hashes do not match, inform user that the transfer was unsuccessful. The server cleans up. The server returns to “wait for operation from client” and client returns to “prompt user for operation” state respecitively. Do not send throughput information.

    3. DEL:
      1. Client sends operation (DEL) to delete a file from the server. Note: you can create a test file called “delete.txt” with randomn strings in the server directory to test the DEL operation.
      2. Client sends the length of the file name which will be sent (short int) followed by the file name (character string).
      3. Server receives the above information, decodes file name size and file name, and checks if the file to be deleted exists or not.
        1. If the file exists, the server sends a positive confirm (integer value 1) back to the client.
        2. If the file does not exit, the server sends a negative confirm (integer value -1) back to the client.
      4. Client receives the confirm from the server.
        1. If the confirm is negative, it prints out “The file does not exist on server” and returns to “prompt user for operation” state.
        2. If the confirm is positive, the client further asks user to confirm if she/he wants to delete the file: “Yes” to delete, “No” to ignore. The client then sends the user’s confirm (i.e., “Yes” or “No”) back to the server.
          1. If the user’s confirm is “Yes”, the client waits for the server to send the confirm of file deletion.
          2. If the user’s confirm is “No”, the client prints out “Delete abandoned by the user!” and returns to “prompt user for operation” state.
      5. The server waits for the delete confirm sent by the client.
        1. If the confirm is “Yes”, the server deletes the requested file and returns an acknowledgement to the client to indicate the success or failure of file deletion operation.
        2. If the confirm is “No”, the server returns to “wait for operation from client” state.

    4. LIS:
      1. Client sends operation (LIS) to list the directory at the server.
      2. Server obtains listing of it's directory
      3. Server computes the size of directory listing and sends the size to client as a 32 bit int.
        1. Client receives the size and read the directory listing.
        2. Once listing is received, client displays listing to user.
        3. Client and server return to “prompt user for operation” and “wait for operation from client” state respectively.

    5. MKD:
      1. Client sends operation (MKD) to make a directory at the server.
      2. Client sends the length of the directory name which will be sent (short int) followed by the directory name (character string).
      3. Server receives the above information, decodes directory name size and directory name, and checks if the directory to be created exists or not.
        1. If the directory exists, the server sends a negative confirm (integer value -2) back to the client.
        2. If the directory does not exit, the server sends a positive confirm (integer value 1) back to the client if the directory is successfully created; otherwise, the server sends a negative confirm (integer value -1) back to the client.
      4. Client receives the confirm from the server.
        1. If the confirm is negative (-2), it prints out "The directory already exists on server" and returns to “prompt user for operation/wait for operation” state.
        2. If the confirm is negative (-1), it prints out "Error in making directory"" and returns to “prompt user for operation/wait for operation” state.
        3. If the confirm is positive, the client prints out "The directory was successfully made" and returns to “prompt user for operation/wait for operation” state.

    6. RMD:
      1. Client sends operation (RMD) to remove a directory at the server. Note: Directory must be empty for RMD to work.
      2. Client sends the length of the directory name which will be sent (short int) followed by the directory name (character string).
      3. Server receives the above information, decodes directory name size and directory name, and checks if the directory to be deleted exists or not.
        1. If the directory exists, the server sends a positive confirm (integer value 1) back to the client.
        2. If the directory does not exit, the server sends a negative confirm (integer value -1) back to the client.
      4. Client receives the confirm from the server.
        1. If the confirm is negative, it prints out “The directory does not exist on server” and returns to “prompt user for operation/wait for operation” state.
        2. If the confirm is positive, the client further asks user to confirm if she/he wants to delete the directory: “Yes” to delete, “No” to ignore. The client then sends the user's confirm (i.e., “Yes” or “No”) back to the server.
          1. If the user's confirm is “Yes” the client waits for the server to send the confirm of directory deletion.
          2. If the user's confirm is “No” the client prints out “Delete abandoned by the user!” and returns to prompt user for operation/wait for operation state.
      5. The server waits for the delete confirm sent by the client.
        1. If the confirm is “Yes” the server deletes the requested directory and returns an acknowledgement to the client to indicate the success or failure of file deletion operation. (Directory must be empty in order for deletion to occur).
          1. If the acknowledgement is positive, the client prints out “Directory deleted” and returns to “prompt user for operation” state.
          2. If the acknowledgement is negative, the client prints out “Failed to delete directory” and returns to “prompt user for operation” state.
        2. If the confirm is “No” the server returns to “wait for operation” state.

    7. CHD:
      1. Client sends operation (CHD) to change to a different directory on the server. Note: You can use CHD followed by LIS to verify that CHD worked successfully.
      2. Client sends the length of the directory name which will be sent (short int) followed by the directory name (character string).
      3. Server receives the above information, decodes directory name size and directory name, and checks if the directory to be changed to exists or not.
        1. If the directory exists, the server sends a positive confirm (integer value 1) back to the client if it successfuly changed directories; otherwise, the server sends a negative confirm (integer value -1) back to the client.
        2. If the directory does not exist, the server sends a negative confirm (integer value -2) back to the client.
      4. Client receives the confirm from the server.
        1. If the confirm is negative (-2), it prints out “The directory does not exist on server” and returns to “prompt user for operation/wait for operation” state.
        2. If the confirm is negative (-1), it prints out “Error in changing directory” and returns to “prompt user for operation/wait for operation” state.
        3. If the confirm is positive, the client prints out “Changed current directory” and returns to “prompt user for operation/wait for operation” state.

    8. XIT:
      1. Client sends operation (XIT) to exit.
      2. Client closes socket, and exits.
      3. Server closes socket and goes back to “wait for operation from client” state.
      4. Client informs user that session has been closed.

    Note: If it is not explicitly specified, the client and server will return to “prompt user for operation” and “wait for operation from client” state respectively after a succesful operation and wait for the next operation.

General Notes

Server Side Design

The server is responsible for handling the connection request from a single client, processing the request, then looping back to handle further requests. For this particular assignment, your code only needs to handle one client at a time. The server binary should be named myftpd.

The server should listen on the specified port number [refer to Appendix for the port number for your group] that is given by command line argument. Your server should bind to the port and then listen for incoming client connections. You may decide if you would like to allow timeouts for better responsiveness but any sort of a timeout is purely optional. You may want to allow for port reuse for quicker recovery after a crash.

Once a new client request arrives, your server should use the accept function to create a new client socket. Once the file has been transmitted, return to the state where your server is waiting for a new command. Your server should be invoked as follows:
./myftpd [Port]

Client Side Design

The client is responsible for initiating a connection to a server. Once connected, the client code should prompt the user for an operation (REQ, UPL, DEL, LIS, MKD, RMD, CHD, XIT), and should transmit the operation to the server. Your client binary should be named myftp. Your client should be invoked as follows:
./myftp Server_Name [Port]

The first argument is the hostname of the server to connect to (this will depend on what machine you start your server code on). The second argument is the port number.

Once a transfer completes successfully, you need to display the throughput for the transfer. You should display information similar to the following for each file transfer (REQ/UPL).

4739823 bytes transferred in 1.00 seconds : 4.740 Megabytes/sec
File MD5sum: d3abf2c9fd87652da48f7298c3cad6a7

Submission

Submit a gzipped tar file of your entire assignment package to your dropbox/program3 directory. The archive must include the following:

Grading Rubric


Appendix A

Table 1. Group Port/ Assignment
TCP Ports to UseGroup Members
41001, 41002Nicholas Aiello, Rosalyn Tan
41003, 41004, 41005Christopher Beaufils, David Lewis, John Ryan
41006, 41007, 41008Theodore Brombach, Emily Obaditch, Matt Reilly
41009, 41010Timothy Chang, Christopher Syers
41011, 41012, 41013Mary Connolly, Paul Dowling, John Rocha
41014John Considine
41015, 41016Aaron Crawfis, Kurt Davis
41017, 41018Jorge Diaz-Ortiz, Jose SuarezMartinez
41019, 41020Jacob Dumford, Tyler Sammons
41021, 41022, 41023Robert Freedy, Nicholas Haydel, Patrick Schurr
41024, 41025Luke Garrison, Nicholas Ward
41026, 41027, 41028Michael Hillmer, Michael Hutchinson, James Ryan
41029Cory Jbara
41030, 41031, 41032Jacob Kassman, Lauren Kuta, Matt Paulson
41033, 41034Reilly Kearney, Ann Keenan
41035, 41036John Klamer, Elizabeth Vista
41037Harrison Le
41038, 41039Andrew Lubera, Alan Vuong
41040, 41041Ryan McMullen, Matthew Perez
41042, 41043Madelyn Nelson, Jenna Wilson
41044, 41045John Nolan, John Riordan