Program 2

Card Dealer


Now that you've got a client implemented to talk to a server, it's time to move to the other end of the socket and implement a server. We'll also mix things up a little and use UDP instead of TCP for this one. To prepare, look at the sections on Datagram Services and Datagram Example in Gary's Unix Network Programming Manual.

Implementing a real server based on a published RFC is too much work for this stage of the game, so you'll be implementing something a little more straight- forward. The server is going to be a card dealer - yes, a card dealer, not a used car dealer. The server will be responsible for maintaining a shoe of multiple decks of cards, and dealing the next card from the shoe whenever a client requests one.

The Server

The usage for the program should be as follows: You can assume that the user won't do something cruel and specify a non-numeric string, a number <= 0, or some really big number for the number of decks or the port number.

When the server starts, it should print the number of decks and the port number it is using, initialize any data structures it needs to represent the shuffled decks, then open a UDP server socket and go into a loop waiting for requests.

The server must support the following requests, submitted as simple ASCII text:

Each request should be terminated with a new-line ('\n') character.

The server should return the following responses:

For those not familiar with regular expression notation, the deal response should contain one character from the list of digits 2-9 and 0, or one of the letters J, Q, K, or A. This represents the value of the card, 2-9, Ten, Jack, Queen, King, or Ace. The response should then have one of the characters C, H, S, or D (for Clubs, Hearts, Spades, or Diamonds).

The SHUFFLE command must cause the server to reinitialize the shoe with the specified number of decks. If the client keeps submitting DEAL requests until all the cards are dealt (52 times the number of decks), you should automatically reshuffle.

Each time the server receives a request, it must print out the IP address and port of the sender (the client), the request received, and the response it is going to send. The responses must be formatted like this:

Make sure you format the output this way, so that it is easy to pick out the cards that the server dealt with a simple script.

One thing that will make this easier than the POP client is the use of the UDP protocol. Each datagram will be a complete message, and you won't have to be concerned about how a request might be split across multiple recv() calls in a stream. Another thing that will be easier is that you don't have to call accept() each time a client wants to talk to you, so the server will only need to deal with one socket. Note that because you are using UDP, you won't be able to call recv() and have it return -1 when the client breaks the connection. You will need to use <CTRL>-C to break out of the program when you are done running it.

The Client

In order to test the server, you'll also need to write a simple client program that will request cards from the server. The usage for the client should be The client should have a simple menu:
  1. Request next card
  2. Shuffle deck
  3. Quit
When the client starts up, it should create a UDP client socket, then enter a loop displaying the menu, getting user input, and executing the requested command until the user selects "Quit". For each card request, the client should print the card that was returned by the server.

Testing

If your server is working correctly, you should be able able to start it with one deck, deal 53 cards, and make sure that for the first 52 it never returns the same card twice (and it always returns a valid card). On the 53rd it will have to start repeating. You should also be able to connect with two different clients, have each of them request 27 cards, and see the same thing.

That's the reason for the specific formatting of the output. Try starting your server with the following command:

The tee command takes a copy of whatever goes to the output and puts it in the specified file too. It's similar to script, but you can't see anything that is typed as input. Start a client, request at least 53 cards, stop the client, then stop the server (with a <CTRL>-C). Then enter the following: This should hopefully show you that each of the cards was only dealt once, except for any after the 52nd, when the reshuffle occurs. Unless you requested more than 104 cards, none of them should have a count greater than 2. To just make sure of the number of different cards dealt, enter the same command line, and add This should return the number of unique lines - this should be 52.

Designing a Solution

Before you jump into an editor and start hacking on code, you really should sit down and think about how you want to implement the program. The networking part of it should be pretty straight-forward, but you'll need to think about how you want to keep track of which cards have already been dealt and how you will randomly choose the next card to deal from the remaining cards. As part of the assignment, you will need to turn in your design documentation; it doesn't need to be anything elaborate, but it should indicate how you are planning to maintain the card data and list the socket calls that you will need to use in the program. I can't make you do the design before you start coding, but try it, you might like it.

Building a Code Library

You should also start trying to clean up and organize your code - as you have probably noticed, a lot of the things you need to do in each program are pretty repetitive. So you should start building some functions that you can reuse. For this assignment, you don't need to split them out, but for the next one, you will need to have a library, so start organizing the code into functions now while you're working on this assignment.

For example, you will probably find it advantageous to have functions like the following as the semester progresses:

You don't need to use these names, or even group the functionality in the same way. But you should be identifying common activities that you need to do that take more than one line of code and are thus candidates for your library. (If they only take one line of code, it's probably better to just call the standard library function and not obscure it with some other name.)

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, and the output from your server for two different test runs. 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. Note that you don't have to capture or turn in the client output, since the server output should include all of the same pertinent information. You can just use tee to capture the server runs, since there won't be any input on the server side.

You should include the following:

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