CSE 333 Exercise 15

Out:   Friday, February 27
Due:   Monday, March 2 by 11 AM
Rating:   3 (note)
CSE 333 Exercise Rating Scale

Each exercise this quarter is rated on a integer scale of 1 – 5, inclusive, with 1 being the "least time-consuming" and 5 being the "most time-consuming".

This difficulty scale is meant as a rough guide for you in predicting the amount of time to set aside for each exercise as you balance the work required for 333 with your other obligations. However, it is necessarily imperfect as everyone's set of circumstances and experiences with the exercises differ. If your experience with an exercise does not align with its rating, that is not a reflection of you or your abilities.

Goals

  • Adapt client-side networking code (TCP) in C++.
  • Use the utility netcat (nc) to interact with clients over the network.

Problem Description

Write a C++ program that:

  1. Connects (via TCP) to a server specified by a user-supplied hostname and port number.
  2. Sends the bytes of a specified local file to the server.
    • Because you must use the POSIX write() to write bytes to the server, we also want you to use the POSIX read() to read in the local file.
  3. Closes the connection and exits.

Your program should accept the command-line arguments in the following order:

  1. The hostname of the server
  2. The port number of the server
  3. The name of a local file

You also need to write a Makefile so that we can compile your code by typing make. Your Makefile should produce an executable binary called ex15 and should only recompile and relink files that need to be rebuilt to bring the program up to date.

An example execution of the completed application is:

$ make
$ ./ex15 localhost 5555 test.txt

Implementation Notes

Modularization

Your code should be modularized nicely. ex15.cc must contain the logic for the client-side networking program. For the remaining logic, consider splitting it into multiple source files if that makes sense – for example, by isolating all of the network-specific code in a module.

Code Adaptation

Feel free to adapt sample code from lecture and section as part of your solution if it helps, but be sure you understand what your code does when you're done.

User Input

Since you will be reading in user input via command-line arguments, you should make sure your code handles various inputs from the user, which may be in an unexpected format. Note that each of the three inputs in this exercise has a different expected format.

Error Handling & Robustness

When you are using POSIX functions, you should handle errors by retrying in the case of recoverable errors (EAGAIN and EINTR) and returning an error status in the case of a non-recoverable error. We recommend writing some utility functions to deal with this. Make sure that you clean up system resources in all possible cases.


Testing Notes

Server Setup

To test your program, you will need to setup a server to receive the data that your ex15 executable will send. The recommended way to do this is using the nc utility:

$ nc -l <port> > output.bytes

This command will run a netcat listener (-l) on port <port> (e.g., 5555), which needs to match the port you provide to the ex15 executable, and redirect any received bytes to the file output.bytes. Note that this will create the file if it didn't exist or overwrite if it does exist.

"Local" Testing on attu

If you are running the server on the same computer/host that you are testing your code on, you can use the special loop-back IP address 127.0.0.1 or localhost to refer to the same host. Each attu (e.g., attu1, attu2) counts as a separate host, so if you are testing on attu, the client and server processes must be running on the same one for this to work. To log into a specific attu machine, run:

$ ssh <netid>@attu<#>.cs.washington.edu

where <#> should be replaced by a number 1 – 8.

Style Focus

C/C++ Idioms

To work with the POSIX networking API, we, unfortunately, have to mix C and C++ idioms in our code. But you should still try to use C++ idioms whenever possible (e.g., use cout instead of printf, use C++ casting).

Submission

Submit the following file(s) by creating an ex15-submit tag in your exercise repository before the assignment deadline. The file(s) should be located in the exact directory listed below, including capitalization:

  • ex15/ex15.cc
  • ex15/Makefile

All other files you wish to submit must be in the ex15 directory – we will grab everything in the directory that exists in the ex15-submit tag.


Your code must:

  • Compile without errors or warnings on CSE Linux machines (lab workstations, attu, or CSE home VM).
  • Have no runtime errors, memory leaks, or memory errors (g++ and valgrind).
  • Have a Makefile as described above that compiles the code with the g++ options -Wall -g -std=c++17.
  • Have a comment at the top of your .cc files with your name(s) and CSE or UW email address(es).
  • Be pretty: the formatting, modularization, variable and function names, commenting, and so on should be consistent with class style guidelines. Additionally, the linter shouldn't have any complaints about your code (cpplint.py).
  • Be robust: your code should deal with hard-to-handle/edge cases and bogus user input (if there are any) gracefully.