The client/server chat program has long been a popular assignment for Java students because it is an excellent example of two important concepts: sockets and threads. A socket represents a persistent connection between two applications – in this case, the chat server and the client.
Threading seems to allow a number of lightweight processes to function concurrently, but it actually works by passing processor control from thread to thread very rapidly. The chat server listens on a port, waiting for clients to connect. When a socket connection is made with a new client, the server starts a thread to manage the flow of messages back and forth.
The chat client is also threaded, because it has to do two things “at once;” it must listen for keyboard input to send to the server, and it must list to the socket’s input stream to receive and print messages coming through the server from other clients. T
There are four code files for this example, which may be downloaded from www.rivervine.com/talkingshop.
Line 10 of ChatServer.java creates a new socket server running on the port specified in line six. The listen method begins waiting for a client to connect on that port. This method will rest at line 18 until a client joins, and the serversocket.accept() call returns a socket connection. A new instance of ServerThread is created for this connection. After starting the thread, control returns to ChatServer and listen() calls itself recursively to wait for the next client.
When ChatClient is run, it connects to the server by specifying the machine name (localhost if the server is running on the same machine for testing) and the port. ChatClient creates a ClientThread, which continues to listen for keyboard input and forwards any message typed to the server. After starting the thread, control returns to ChatClient which loops to listen for messages coming from the server.
When a ServerThread receives a message from a client, it calls the static broadcast method in the ChatServer class. The broadcast message loops through all of the ServerThreads, delivering the message to each of them. In this way, text sent by one client is received by all.
This is a fairly basic example, and has no GUI (command line only). It also lacks error handling – if a client disconnects, an exception will be thrown when the server tries to broadcast to it. If you’d like to play with the code and improve on it, I’d be happy to put the results on the Web as well. Mini open-source project, anyone?
Cooney is a managing partner and chief software architect for Rivervine Technologies Inc. Contact: robert.cooney@rivervine.com.