CS 212 - Project Phase 2: Adding Networking

Summer 2003

Due: 11:59pm, Monday, July 21


0. Objectives

In the first part of the project, you created the GUIs for the client and server. Currently, these GUIs do little more than print messages to the console. In this assignment you will write code in both your client program and server program to allow the server and clients to communicate, thus allowing users to log in to the server and cast votes.

Note that for this assignment you may use my solution files from part1, your solutions for part1, or any other group's solutions (with their permission, of course).


 

1. Client Specifications

You should modify your client to function as follows:

  1. When the client program first starts, it displays the GUI. It should no longer read in the ElectFile.txt file; it will get election information from the server at a later step.


  2. The client presses the "Connect" button to connect to the server. The connection dialog pops up, prompting the user for his username and password.  After the user enters this information and clicks "OK", the client should open a connection to the server, send the username and password, and indicate that the user is trying to connect.

    Note that if the user clicks "Cancel" or closes the dialog box, no connection should be made.


  3. The server will receive the username and password. For now the server should just blindly accept the username and password, and send a list of elections and their candidates to the client. This will be explained in more detail in the Server section.

    In the 3rd assignment, when we include security, the server will check the username and password with a list of <username, password> pairs that it has. It will either respond that the pair is not valid (either the username doesn't exist or the password is incorrect), or, if the pair is valid, it will send a
    list of elections and their candidates to the client. 


  4. The client will receive the election information and display it on screen.  Remember that the client should not display election status or vote counts. Now the user can either vote or disconnect. 


  5. If the disconnect button is pressed, the client should end the connection with the server.


  6. If the vote button is pressed, the client should pop up an authentication dialog box asking for username and password, just like the one that pops up when connecting to the server. When the box is filled out and the user presses OK, the username, password, election name, and candidate name should all be sent to the server.


  7. The server receives this information. Again, the server won't be checking the username and password yet. However, it should keep a record of all users that voted in each election (where is the best place to store this information?). Each time a user votes, the server should check to see if that user has already voted in that election. If so, it should send a message to the client that the user already voted. If the user hasn't voted in that election, the server should tally the user's vote and send a message to the client that the vote was successful.

    In the 3rd assignment, the server will also have to check if the username and password are correct.


  8. As stated above, you should not allow a user to successfully vote more than once in each election. Also assume that all usernames are unique.


2. Server Specifications

In this part of the project, you will improve the server to allow it to listen for incoming connections and serve them. First, note that the "Test vote" button from part 1 is no longer needed, so you can remove it. 

The server should function as follows:

  1. When started up, the server reads in the ElectFile.txt file and displays the election information on screen.


  2. The server is expected to reside on some well-known network address, so its IP address should be known to all clients. The server listens on a well-defined port number (for example, 6789) for incoming connections from clients. This port number should be a command-line parameter for the program. (NOTE: to have the client and server connect through TCP on the same computer, have the client connect to "localhost" (instead of an IP address) on the same port as the server.
  3. When detecting an incoming connection, the server should spawn a new thread to handle that connection.


  4. The first message the server should receive is an attempt to open a connection with the server, along with a username and password.  For now the server will ignore the username and password, and simply accept the connection. It will then send the set of all elections and their candidates to the client. At this point the client can either vote or disconnect. 


  5. If the client disconnects, the server should terminate the thread. This can be done by simply exiting the thread's run() method, at which point the thread will die.


  6. If the client votes, it should send a username, password, election name and candidate name. The server should first check if the user has already voted in the specified election. If so, the server sends an error message back to the client that the user has already voted in that election. If the user has not voted in that election, the server should tally the vote, record that the user has voted in that election, and send a message to the client indicating that the vote was successful.


  7. If an election is opened, the server should not only reset all vote counts in that election to 0, but should also erase the list of users that have voted in that election.


  8. The server waits for the next request from the client. If you want to be fancy, you can terminate the connection to the client is ever idle for a given amount of time.

2.1 More Server Notes

The "Open", "Close", and "Refresh" buttons should still function as they did in part 1 of the project. You should remove the "Test Vote" button, however.

 

3. More Notes

3.1 A Note on Threads

When connecting, the client should spawn and start() a new thread to handle that connection. The reason for this is that handling a connection takes a long time (indeed, it takes as long as the connection is open). You'll remember that event-handling code must execute quickly, or else the GUI will freeze, so we cannot handle the connection there. Instead, you should spawn a new thread in your event-handling code and start() it, so that the new thread will handle the connection, and the event-handling thread will be able to continue without delay.

On the server side, you should spawn and start() a new thread to handle each new incoming connection. It would be impossible to serve multiple connections with one thread.

I will be talking about threads in class. You should also look at the Java Tutorial and the Java API.

Also, remember to use the "synchronized" keyword where necessary. Again, I'll explain this in class. Basically, synchronized prevents methods called from two different threads from trying to access a data structure at the same time. If this happens, data can be corrupted.

3.2 A Note on Serialization

Serialization allows objects to be "frozen", saving their state. These serialized objects can then be sent across a network, or even saved to disk.  For this project, you should use serialization to send objects across the network. To serialize an object, you first must make sure that the object's class implements the Serializable interface. There are no methods to write here, so just add " implements Serializable" when you declare your class. You must also make sure that any objects contained within that class are also serializable. 

Check out the Serializable interface in the API. Also look at the ObjectInputStream and ObjectOutputStream classes, which allow you to read and write objects to/from streams. I'll have an example of this in class, in which I save an object to a file, and then reload it.

I recommend writing a Message class, which should include all the information/objects that you want to send over the network. You can then serialize a Message object, send it over the network, and deserialize it on the other end.

Note that if two programs are sending objects between each other, they must both have a copy of that class in order to recognize it. In other words, if you have a Message object, you must include Message.java in both your client and server programs.

 

 4. Design Priorities

The software you design should show good class structure and be easy to extend.  Good documentation, good structure, clean abstractions, and straightforward control flow all contribute to such extensibility. You should also make proper use of Java’s many data structures, such as hash tables, linked lists, etc. (if and where you think you need them).  Think about what classes and class structure you’ll need beforehand, and what those classes should do.

 

5. General Specifications

 

6. Partners and Other Important Information

As before, you can work in a group of 1-3 people total. You may work in a group different from your part 1 group if you like. 

You may use any group's part 1 programs to do this assignment, or you may use my solution files if you wish.

 

7. Submission

You should send your project submission to my email address (ejk16@cornell.edu).  Please put all submitted files in a .zip file whose name has the format "proj2_<netid>.zip", where <netid> is the netid of one of your group members.  For example, I would submit a file called "proj2_ejk16.zip".

Your zip file should contain the following files (at least):