CSE 333 Exercise 16

Out:   Monday, March 2
Due:   Wednesday, March 4 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 server-side networking code (TCP) in C++.
  • Facilitate an exchange of data between a client and a server.
  • Use the md5sum utility to verify file integrity.

Problem Description

Write the server to go along with ex15. It is a C++ program that does the following:

  1. Accepts a port number to listen to as its only command line argument.
  2. Creates a TCP listening socket on the supplied port number and waits for a client to connect.
  3. Once a client connects: reads data from the connected client socket and writes it to stdout until there is no more data to read from the client (i.e., until EOF or a socket error occurs).
  4. Once all of the data has been read and written: closes the client socket and the listening socket, and then exits.

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 ex16 and should only recompile and relink files that need to be rebuilt to bring the program up to date.


Implementation Notes

Modularization

Just like the previous exercise, your program should be modularized nicely. ex16.cc must contain the logic for the server-side networking program. Consider splitting it into multiple source files if that makes sense, for example by isolating all of the network-specific code in a module.

Socket Reading

You should use read to read from the input client socket. Pay attention to the possibility that read might return EINTR or EAGAIN, and they might read less than you ask for. We recommend writing some utility functions to deal with this. Feel free to use fwrite to write to stdout if you like.

Adapting Code

As with the previous exercise, feel free to adapt sample code from lecture and section as part of your solution if it helps (it probably will), but be sure you understand what your code does when you're done.

Repeats From Exercise 15

You have less user input than before (just one format to worry about), but it still needs to be handled robustly. Error handling for the POSIX functions you use is the same here: retry when recoverable errors occur, or return an error status for unrecoverable errors.


Testing Notes

To test your program, try running it on a specific attu machine, say attu4.cs.washington.edu, and use your ex15 binary to send it a file. For example, on attu4.cs.washington.edu, run the following command:

./ex16 5555 > output.bytes

Then, on some client machine, pick a file to send to your server. For example, this command will send the ex15r binary to the server (assuming that the server is running on attu4):

./ex15 attu4.cs.washington.edu 5555 ex15

Once the file has transferred, you should use md5sum to verify that the file was sent correctly. For example, on the server, run this:

md5sum output.bytes

and on the client, run this:

md5sum ex15
and you should see the same MD5 signature printed out on both ends.

Style Focus

Even More Modularization

We've asked that your code is modularized nicely, but as with exercise 15, this can be tricky when we're working with low-level networking code. We've provided some suggestions (helpers for POSIX error handling, separate module for networking code), but it's up to you to determine the best way to structure your code. When doing so, consider good practices that we've' talked about before (in this class or others), such as ensuring that modules you create only have one responsibility each. For example, our suggestion to make a module for networking code follows this idea.

Submission

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

  • ex16/ex16.cc
  • ex16/Makefile

All other files you wish to submit must be in the ex16 directory – we will grab everything in the directory that exists in the ex16-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.