Practice Exercise #12

Write the server to go along with ex11. More specifically, write a C++ program called "ex12" that accepts one command line argument: a port number to listen to. The program should create a TCP listening socket on the supplied port number. When a client connects, the program should create a ptheads thread to handle that connection, while the main thread returns to wait for the next client connection.

Handling a connection means reading from it until there is no more data available. The per-connection thread should write the data it receives to a file. The name of the file should be generated using mktemp with template "fileXXXXXX" (man 3 mktemp). Once all of the data has been read and written, the thread should sleep (man 3 sleep) for 10 seconds and then terminate.

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

./ex12 5555

Then, on some client machine, pick a file to send to your server. For example, this command will send the 'ex11' binary to the server:

./ex11 attu4.cs.washington.edu 5555 ex11

Once the file has transferred, you should use md5sum (man md5sum) to verify that the file was sent correctly. For example, if the file transfer created a file named fileGcs73a on the server, run this:

md5sum fileGcs73a

and on the client, run this:

md5sum ex11

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

Additionally, if two or more clients connect nearly simultaneously to your server their file transfers should execute concurrently, meaning that the file transfers should complete promptly (much more promptly than the 10-seconds the threads sleep).

There are a few requirements on your code:

  • you should modularize it nicely; consider splitting it into multiple source files, for example by isolating all of the network-specific code in a module.

  • you should use read() to read from the input client socket. Pay attention to the possibility that read might return EINTR, and it might read less than you ask for. I recommend writing some utility functions to deal with this. Feel free to use fwrite() to write to stdout.