Homework 3: writing full servers

Serving multiple clients edition!

For this assignment you will extend your war server to accept an arbitrary number of simultaneous connections. Furthermore, while refactoring the server to accept multiple simultaneous connections using multiple processes or threads will get the job done, we will be using non-blocking input/output.

When you originally wrote your code for homework 2, you most likely did something that basically looked like this:

 new_command = recv(2)
 if(parse_cmd(new_command) == "want game"):
   send(get_half_deck())
 else:
   cry_about_error()
 new_command = recv(2)

Note that, whenever you call recv, you are implicitly causing your program to yield the processor until data comes in. If you were trying to serve multiple games at the same time, no matter how many valid commands are waiting on other sockets, you won’t read them until you first receive bytes on the socket you are currently calling recv on. This blocking I/O is easy to understand but does not allow one to write high performance code.

We can solve this problem in one of two basic ways. Most easily, we can simply spawn multiple threads of control, and each thread can block while listening for new data. This is a very simple approach, however it incurs extra overhead for each thread/process spawned. Alternatively, we can keep all of the sockets in the same thread, and tell the operating system to notify us whenever ANY of those sockets has data waiting to be read by the process. The challenge, however, is that rather than being able to sprinkle your code with recv calls wherever you choose, you can only receive data at one point in your code, and then you must manually keep track of the state each connection is in.

Startup hints: C

In C, event driven networking code can be written using the select command. Basics of using select are available at this link.

Startup hints: Python

Because Python is built on top of C, select is built in to Python as well with largely the same semantics.

Startup hints: Java

For those using Java, I recommend using Selectors. As Java is not our expertise or the focus of this class, there may be better alternatives. If you are going to use an alternative feature of the language, please see me to explain that feature is and how it works.

all other languages

Please see me and explain to me the language primitive you will be using if it is not any of the above.

Requirements

Your code can only have one thread of control. Attempting to turn in a solution for grading with multiple threads will be considered cheating. If you have any doubt about your solution’s legality, please contact the professor or TA.

Your code must allow multiple clients to connect simultaneously. There is no requirement that any specific client be paired with any other client. Your code should easily handle up to 100 simultaneous games, and ANY game having 2 client commands being ready should see forward progress (i.e. you can’t be waiting on a separate socket when new data is available).

Turn-in instructions

While this project allows you to use any langauge you want, you need to ensure that we will be able to grade your submission on our class Ubuntu VM. If you need to install the jvm, compile source files, or otehrwise prepare the environment, you’ll need to provde a Makefile which will do so. You will also provide a server.sh script which we can run to start the code. server.sh will take one argument:

./server.sh [portnumber]

It will then listen for connections, and pair up 2 connecting clients for a game of war using the v.1 protocol.

Your server must listen for connections on both its ipv4 and ipv6 addresses.

Grading

We will run your server against a reference implementation for the server and clients. If at any time a client sends an incorrect message, your code should close the connection for BOTH clients, but otherwise continue operating.

We will connect to your server with a combination of buggy clients (that either send the wrong thing, don’t send anything, or send something but not enough to kick them or continue), laggy clients, and correctly operating clients. Your server should not exit when anything unexpected happens, but rather close client connections and continue accepting new connections and supporting current games.

Any output to stdout or stderr will not be considered - feel free to send debugging output, the result of each war, etc, to the screen.

Due date

This assignment is due Wednesday, September 23. Please get started early.