The central time keeper will be a class that keeps track of the following information:
Every two seconds your program should print an updated scoreboard showing each thread's contestant number (which will be a number from 1 to n where n is the number of contestants), the number of segments completed by the contestant, the contestant's cumulative time to complete these segments, and if the thread reported a new result in the last two seconds, then the time of the last segment completed by the contestant (this last piece of information will help both you and the TA determine what is happening in your program). Once all the contestants have finished, your program should print both the final scoreboard and the order in which the contestants actually finished, by printing the finish queue. You will need to implement a separate thread for this reporting task, although you may place the methods for printing the scoreboard and the finish queue in the time keeping class (the reporter thread will call these methods).
Additional requirements:
Sample Executable
/home/bvanderz/cs365/hw/hw8/race.jar contains a sample executable for this problem. A sample invocation for 3 contestants would be:
java -jar race.jar 3
UNIX> java jtalk.ChatServer port Chat-Room-Names ...For example, if you'd like to serve chat rooms for football, bridge and politics on port 8000, you would type:
UNIX> java jtalk.ChatServer 8000 Football Bridge PoliticsYou will need to be on the server machine when you launch the chat server.
The syntax for attaching a client to the server is:
UNIX> java jtalk.TalkClient hostname portname chatnameSuppose, I have launched the chat server on hydra4.eecs.utk.edu using port 8000 and a person wishes to attach to the server with the chatname "Dr-Plank". The person would type:
UNIX> java jtalk.TalkClient hydra4.eecs.utk.edu 8000 Dr-PlankHere is a sample chat between a number of users (dark red input is what the user types in the console window):
UNIX> java jtalk.TalkClient hydra4.eecs.utk.edu 8000 Dr-Plank Bridge: Football: Politics: Enter chat room: Bridge Dr-Plank has joined There's no one here... Dr-Plank: There's no one here... Goofus has joined Hi Goofus -- do you like bridge? Dr-Plank: Hi Goofus -- do you like bridge? Goofus: Bridge? You mean that card game my gramma plays? Indeed Dr-Plank: Indeed Goofus: Loser. Bye. Goofus has left Can't say I liked him. Dr-Plank: Can't say I liked him. Gallant has joined Gallant: Hi Dr. P Greetings, Gallant Dr-Plank: Greetings, Gallant Gallant: After memorizing your lecture notes, Gallant: I like to read books on bridge. I will recommend you for many jobs & scholarships. Dr-Plank: I will recommend you for many jobs & scholarships. <CNTL-C> UNIX> |
On cetus4:
UNIX> java jtalk.TalkClient hydra4.eecs.utk.edu 8000 Goofus Chat Rooms: Bridge: Dr-Plank Football: Politics: Enter chat room: Bridge Goofus has joined Dr-Plank: Hi Goofus -- do you like bridge? Bridge? You mean that card game my gramma plays? Goofus: Bridge? You mean that card game my gramma plays? Dr-Plank: Indeed Loser. Bye. Goofus: Loser. Bye. <CNTL-C> UNIX> UNIX> java jtalk.TalkClient hydra4.eecs.utk.edu 8000 Gallant Chat Rooms: Bridge: Dr-Plank Football: Politics: Enter chat room: Bridge Gallant has joined Hi Dr. P Gallant: Hi Dr. P Dr-Plank: Greetings, Gallant After memorizing your lecture notes, Gallant: After memorizing your lecture notes, I like to read books on bridge. Gallant: I like to read books on bridge. Dr-Plank: I will recommend you for many jobs & scholarships. Dr-Plank has left I didn't get a chance to be more sycophantic! Gallant: I didn't get a chance to be more sycophantic! <CNTL-C> UNIX> |
To be descriptive, when a client joins, the server sends it information about the current chat rooms. The chat room names will be listed lexicographically, and the name of each person chatting should be listed with each chat room, separated by a space. The order of that listing should be the order in which the chatters joined.
The client then prompts the user for a chat room. It should error check for a bad chat room but do not worry about a premature EOF. Once the person joins the chat room, a message is sent to all others in the chat room that the person has joined. Lines of input entered by the clients are sent to all the clients in the chat room.
The server should support any number of clients, and should work seamlessly when clients leave, as Goofus, and later Dr-Plank did above. The server must not print any output. Feel free to add output to your server while testing it, but please remove it in your final submission. We will only test the behavior of the clients.
Structure
This lab is involved, and will use Java threads, synchronized methods (in place of the C mutexes and condition variables you used in the CS360 C implementation), and Java sockets. If you are having trouble getting started with the lab, look at the Java KnockKnock server socket tutorial, as its structure is what you should start with. At the bottom of the tutorial is an implementation for a multi-client KnockKnock server, which is what I used to start writing the client and server classes for this assignment.
Server Side Implementation
Suppose there are r chat rooms and c clients. Then your ChatServer will have c+1 threads and r instances of a chat room class named ChatData that will handle the message traffic for the chat rooms. Note that unlike the CS360 JTalk lab, you will not use threads to implement the chat rooms.
Your c+1 server threads will be allocated as follows:
Your synchronized methods and data will be restricted to the ChatData objects. Each ChatData object needs to keep track of which clients have been allocated to it, so that it can distribute messages to these clients. My ChatData object had 4 primary methods:
You are free to design your own implementation of ChatData and do not have to use the above structure.
Client Side Implementation
The TalkClient class will use main to establish a connection to the server and select a chat room. You will then face the problem of having to listen to two input streams: 1) stdin, where the user can enter new messages that you should send to the server, and 2) the socket's input stream, which will send you the list of messages to print in the chat window. You can't listen to two streams at once, since you will have to block while listening. Hence you will need to fork a thread that listens to one of the two streams, while main listens to the other stream. You will be managing three streams: 1) stdin, 2) the socket's input stream, and 3) the socket's output stream. You will pass lines from stdin to the socket's output stream. The output stream will in turn send them to the server. Finally, the server will send you lines to print in the console window via the socket's input stream.
You may want to draw yourself some pictures to help visualize the interactions between the server client threads, the chat data objects, and the threads on the client side.
Example Server and Clients
I have included two jar files named ChatServer.jar and TalkClient.jar with this assignment. They are located on the hydra machines at /home/bvanderz/cs365/hw/hw8/. You can run them if you have questions about how your program should work. The output from them is a bit different then the output in the examples. That is fine. Add blank lines if you like to make the output easier to read.