Program 6

TCP Card Dealer - asynchronous I/O


For this program, you will again be modifying your TCP card dealer server to use a different technique for handling multiple clients. This time, you will be back to a single-process model, but you will use asynchronous I/O to handle messages from clients. In this context, the use of the word asynchronous means that there is no coordination between your program and the operating system regarding the timing of network-related activities. In each of the past network programs you have done, you have decided at what point in the execution of your program you would interact with the OS to do some "networking stuff". With asynchronous I/O, this will no longer be the case. Your program can be blissfully doing other tasks, and the operating system can interrupt the flow of the program to tell it to go process a network-related event.

If you remember from your architecture class, this is the software equivalent of a hardware interrupt. It is also similar to the concept of events in Java or Windows programming. You can think of one of these asynchronous interrupts as the equivalent of an event for which you have registered a handler; at the time the event occurs, your program goes of to run the event handler.

In Unix, the basic mechanism for these software interrupts is the signal. Unix defines 32 different signals that the OS can generate; these go by catchy names like SIGTERM (for the termination signal), SIGHUP (for hang-up), etc. Each of these names is just a #defined constant represtenting a number between 1 and 32. Your program can install a signal handler for any one of these interrupts in order to execute application code to deal with the condition that caused the signal to be generated. You can install multiple signal handlers if you need to deal with different signals. Remember that if you haven't installed a signal handler, the C runtime code provides a default one that is executed.

For network programs, you will be interested in SIGIO. Take a look at the information on asynchronous I/O in the Unix Network Programming Manual. I also have some more information from Advanced Programming in the UNIX Environment, 1st Ed. by W. Richard Stevens.

This version of your card dealer must use asynchronous I/O to deal with client connections. There are several ways in which this could be accomplished; one of them is to leave the server socket you create to listen for connections in normal synchronous, blocking mode, but to change every new child socket to asynchronous non-blocking mode. Then you can implement a SIGIO handler that will only need to deal with client requests, and the main program loop can do a normal blocking accept() on the server socket. An alternative would be to put the server socket in asynchronous mode, then just sit in a loop in the main program doing pause() and handling new connection requests and client requests in the signal handler.

Note that your signal handler will be called any time there is a SIGIO signal, so it doesn't differentiate among the different client connections that might have generated the signal. You will need to figure out which one (or ones) caused the interrupt and handle those connections. You can do this with a select() inside the signal handler.

Just like with the previous program where you implemented child processes to handle the client connections, this program doesn't appear to be saving any work over the version that just used select() in the main loop. This is true; you still need to do the select(), you are just doing it in a signal handler instead of the main loop. Once again, the benefit is that when you aren't in the signal handler responding to an I/O event, the program can be doing other things instead of waiting for something to happen on a socket.

The requirements for this program are thus the following:

Design

There is not a lot of design work to be done here, but you should plan how you will implement the signal handler, what you want to do with the main server socket, and how you will handle the processing of client requests and how you will do that from the signal handler.

Adding onto Your Code Library

You should continue to refine the library of socket functions - for instance, you might add routines to the server code that allow you to set a socket for asynchronous operation, and to install a signal handler.

Assignment Submission

NO hard copy, please. Everything should be submitted via email by the due date - mail everything to Anthony. Follow Anthony's specifications for assignment submissions. You need to include the design, your source for the main application, your source for your library, and the output from your server for two different test runs. (You don't need to include any source for the client, since it should be the same as last time.) For the first test run, start the server with one deck and choose one of the ports designated for the lab (40000-40007). If your server can't open a socket on that port, try another one; you should succeed before you exhaust all eight possibilities. Start a client in another window and request twenty cards, shuffle, then request five more cards. For the second run, start the server with four decks, choosing the port as in the previous run, then start two different clients and request twenty cards from each. (These are the same test runs as you did for the last program.)

You should include the following:

The first item should just be in the body of the email - attach the design, source, and output as separate files.