Project 5: Chat Program

Due: November 14

Specification

Write a multi-threaded chat client program.

GUI

Your program should have a GUI that contains a text area for the chat transcript and a text field for the user to enter new messages. The text area should have vertical scroll bars and should wrap lines at word breaks. Include a Disconnect button that sends the disconnect message to the server when the user clicks on it. You can optionally include a Send button that the user clicks when a message is ready to send.

Threads

Your program should have an inner class that extends Thread. When your program starts it should create an instance of this class and start it running as a separate thread which waits for messages from the server and then copies each message to the text area.

Server

You won't write a server program for this assignment, but you will need a server to test your client. To keep things simple at first, use the time server described in the book

I suggest that you start by using the EchoServer program in our textbook (pp. 194 to 196, Vol. II, Chapter 3, 9th ed.). The book's source code is available from http://horstmann.com/corejava.html. Change the server to listen on port 4688 instead of 8189 as it does in the book's code.

After you get your client to work with the EchoServer program, start testing it with the chat server code available in the description of the chat protocol below.

Client

Start with the SocketTest program in our textbook (Vol. II, page 189 in the 9th ed., page 173 in the 8th ed.) and make sure it works with the time server shown in the book.

Next, change the address in SocketTest to "localhost" and the port number to 4688. Add code to get the output stream for the socket and write a test message to the server. You can see an example of how to get the input and output streams for a socket in EchoServer.java (starts on page 194 Vol. II 9th ed., page 179 8th ed.). Create a Scanner for reading from the socket and a PrintWriter for writing to the socket. Your client should use the Socket class, not the ServerSocket class shown on line 18, and it does not need to call the accept method (line 21).

Change the port number in EchoServer to 4688 also. Compile both programs and then test them by running them in separate shell windows. Make sure you start the server first. When you run the client, it should get the test message back from the server.

Once you have a simple command-line client working, you can add the GUI and the additional thread. The new thread will only read from the socket, and the event-handling (GUI) thread will only write to the socket. Then go on to implement the protocol described in the next section.

Your chat client should get the user name and port number from the command line. The user name should default to Anonymous and the port number should default to 4688. For example, this command line:
      java ChatClient Frodo 4600
would use Frodo for the user name and connect to port 4600 on the server. The user should be able to specify a user name without a port number. In that case the program should use the default port number (4688):
      java ChatClient Bilbo

A (Very) Simple Chat Protocol

After connecting to the server (on port 4688) the client should send a message as follows:
connect UserName
to tell the server what name to add to the beginning of each message sent out from this client.

Messages are delimited by newline characters and have no special format. (This could be changed in the future if we make new versions of the protocol.)

When the server receives a message from a client, it adds the user name for that client to the beginning of the message and then sends the message to all clients except the client from which it received the message. That means that your client must add its own messages to the text area in addition to sending messages to the server.

A client sends the following message to disconnect:
disconnect UserName
The server will notify all other clients of the disconnection and will send the message disconnected back to the disconnecting client before closing the socket.

Your program will not receive full credit unless it works with the chat server in the chat2014.jar file.

Here's a version of the chat server that was compiled with Java 1.6, in case you are using an older version of Java: chat1_6.jar
(The other version was compiled with Java 1.8.)

The chat2014.jar file is not executable so you have to remove the files from the jar before running the server. You can remove the files with the command:
     jar xf chat2014.jar
You can run the server from the command line with the command:
     java ChatServer
To run client programs at the same time, you will need to run the server in the background on Unix-type systems or in a separate command window on Windows. You can run the client program in the jar file with the command:
     java ChatClient UserName

Synchronization

Because the text area is accessed by more than one thread (the main thread and the thread that waits for messages from the server), it is a shared resource and access to it must be synchronized.

Turn in

Name the main class of your program ChatClient. Put your source and class files into a jar file and turn the jar file in on Canvas. Please do not put your classes in a package. Your files should not be inside a folder in the jar file, and there should not be any files other than source files, class files, and an optional README.txt file.

Points

  10 Gets user name and port number from command line
  10 Text area with vertical scroll bars, working disconnect button
  10 Inner class that extends Thread
  10 Copies text field input to text area
  15 Starts new thread to read from server
  10 Text area is accessed only by synchronized code
  15 Sends text field input to server
  20 Receives messages from server and copies to text area
100 TOTAL

NOTE: If you don't turn in source code you won't receive credit for making an inner class, starting a new thread, or synchronizing access to the text area.