Recitation 9: Networking with the Sockets API

For this recitation, you will implement a very rudimentary “dropbox” system, tcp-dropbox, where clients upload files to a long-running server.

You should clone the skeleton code from here:

git clone ~j-hui/cs3157-pub/examples/tcp-dropbox

In there, you will find the source code for tcp-dropbox-client, and skeleton code for tcp-dropbox-server. Your job is to implement tcp-dropbox-server. You will also find the solutions in tcp-dropbox-server-sol.c, which you can build and run yourself, as well as a Makefile that builds everything there.

9.0 Using tcp-dropbox

You should start the tcp-dropbox-server like this:

tcp-dropbox-server <server-port> <filebase>

tcp-dropbox-server will listen for TCP connections from on <server-port>. Then, you can upload a file using tcp-dropbox-client like this:

tcp-dropbox-client <server-ip> <server-port> <file>

It will connect with the server and send the contents of <file> to tcp-dropbox-server, according to our own tcp-dropbox protocol. tcp-dropbox-server will then write those file contents to a file named <filebase>.<N>, where <N> is the number of connections it has received since it started running. For example, if you run tcp-dropbox-server with hello as your <filebase>, then tcp-dropbox-server will write uploaded file content to hello.0, hello.1, hello.2, etc. for each client connection.

Try doing this with the tcp-dropbox-server-sol executable and upload some files using tcp-dropbox-client.

9.1 Understanding the tcp-dropbox protocol

tcp-dropbox-client and -server are supposed to follow a specific protocol when communicating with one another, which we call the tcp-dropbox protocol. (This protocol was made up for the purposes of this example; to my knowledge it isn’t a real protocol used anywhere else.)

This protocol is documented in the README.txt, but before you read it, try to figure out what the protocol is by reading tcp-dropbox-client.c, and playing with the executable. Write down what you think the protocol is, as precisely as you can (account for every byte sent through the TCP connection).

Here are some hints and leading questions to get you started?

  • Unlike HTTP, the tcp-dropbox protocol is not a textual protocol.
  • tcp-dropbox-client.c only uses send() and recv() to send and receive bytes; you should read their man pages to see what each parameter is.
  • Does tcp-dropbox-client send the file name of what it is uploading?
  • Does tcp-dropbox-client send the size of what it is uploading? How many bytes does it send, and in what kind of encoding?
  • Does tcp-dropbox-client receive anything from the server? If so, why?

9.2 Planning out tcp-dropbox-server

Now that you understand the protocol, write down in pseudocode what you think the server should do to implement its half of the protocol.

Don’t forget to make your pseudocode server handle multiple clients!

9.3 Implementing tcp-dropbox-server

Now, implement tcp-dropbox-server based on your pseudocode. Here are some hints and tips:

  • Don’t try to code the entire server all at once.

    • Implement each stage of the protocol one at a time.

    • Handle only a single client connection at first before worrying about looping back around to handle more client connections.

  • You may use file descriptors (with send()/recv()) or FILE pointers (with fread()/fwrite()); you can choose to use either.

    • Stick to whichever you choose: don’t use file descriptors once you’ve wrapped them in FILE pointers.

    • If you use file descriptors, you should use the MSG_WAITALL flag with recv() to ensure that you receive all the bytes you request.

    • If you use FILE pointers, make sure you’re aware that FILE pointers are block-buffered for write operations.