Multithreaded Chat Client
Multithreaded Chat Client
* For each accepted client, a ClientListener and ClientSender threads are created and
started. A ClientInfo object is also created to contain the information about the client.
Also the ClientInfo object is added to the ServerDispatcher's clients list. When some
client is disconnected, it is removed from the clients list and both its ClientListener and
ClientSender threads are interrupted.
* ChatServer class is entry point for the program. It opens a server socket, starts the
dispatcher thread and infinitely accepts client connections, creates threads for handling
them and starts these threads.
*/
import java.net.*;
import java.io.*;
public class ChatServer
{
public static final int LISTENING_PORT = 2002;
public static void main(String[] args)
{
// Open server socket for listening
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(LISTENING_PORT);
System.out.println("ChatServer started on port " + LISTENING_PORT);
} catch (IOException se) {
/**
* @return and deletes the next message from the message queue. If there is no
messages in the queue, falls in sleep until notified by dispatchMessage method.
*/
private synchronized String getNextMessageFromQueue()
throws InterruptedException
{
while (mMessageQueue.size()==0)
wait();
String message = (String) mMessageQueue.get(0);
mMessageQueue.removeElementAt(0);
return message;
}
/**
* Sends given message to all clients in the client list. Actually the
* message is added to the client sender thread's message queue and this
* client sender thread is notified.
*/
private synchronized void sendMessageToAllClients(String aMessage)
{
for (int i=0; i<mClients.size(); i++) {
ClientInfo clientInfo = (ClientInfo) mClients.get(i);
clientInfo.mClientSender.sendMessage(aMessage);
}
}
/**
* Infinitely reads messages from the queue and dispatch them
* to all clients connected to the server.
*/
public void run()
{
try {
while (true) {
String message = getNextMessageFromQueue();
sendMessageToAllClients(message);
}
} catch (InterruptedException ie) {
/**
* ClientInfo class contains information about a client, connected to the server.
*/
import java.net.Socket;
public class ClientInfo
{
public Socket mSocket = null;
public ClientListener mClientListener = null;
public ClientSender mClientSender = null;
}
/**
* ClientListener class is purposed to listen for client messages and
* to forward them to ServerDispatcher.
*/
import java.io.*;
import java.net.*;
public class ClientListener extends Thread
{
private ServerDispatcher mServerDispatcher;
private ClientInfo mClientInfo;
private BufferedReader mIn;
public ClientListener(ClientInfo aClientInfo, ServerDispatcher aServerDispatcher)
throws IOException
{
mClientInfo = aClientInfo;
mServerDispatcher = aServerDispatcher;
/**
* Sends messages to the client. Messages are stored in a message queue. When the
queue is empty, ClientSender falls in sleep until a new message is
arrived in the queue. When the queue is not empty, ClientSender sends the
messages from the queue to the client socket.
*/
import java.io.*;
import java.net.*;
import java.util.*;
}
/**
* Sends given message to the client's socket.
*/
private void sendMessageToClient(String aMessage)
{
mOut.println(aMessage);
mOut.flush();
}
/**
* Until interrupted, reads messages from the message queue
* and sends them to the client's socket.
*/
public void run()
{
try {
while (!isInterrupted()) {
String message = getNextMessageFromQueue();
sendMessageToClient(message);
}
} catch (Exception e) {
// Commuication problem
}
// Communication is broken. Interrupt both listener and sender threads
mClientInfo.mClientListener.interrupt();
mServerDispatcher.deleteClient(mClientInfo);
}
}
Client For Chat Server
/**
* ChatClient connects to Chat Server and prints all the messages
* received from the server. It also allows the user to send messages to the
server.ChatClient thread reads messages and print them to the standard output. Sender
thread reads messages from the standard input and sends them to the server.
*/
import java.io.*;
import java.net.*;
public class ChatClient
{
public static final String SERVER_HOSTNAME = "localhost";
public static final int SERVER_PORT = 2002;
public static void main(String[] args)
{
BufferedReader in = null;
PrintWriter out = null;
try {
// Connect to Chat Server
Socket socket = new Socket(SERVER_HOSTNAME, SERVER_PORT);
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()));
System.out.println("Connected to server " +
SERVER_HOSTNAME + ":" + SERVER_PORT);
} catch (IOException ioe) {
System.err.println("Can not establish connection to " +
SERVER_HOSTNAME + ":" + SERVER_PORT);
ioe.printStackTrace();
System.exit(-1);
}
// Create and start Sender thread
Sender sender = new Sender(out);
sender.setDaemon(true);
sender.start();
try {
// Read messages from the server and print them
String message;
while ((message=in.readLine()) != null) {
System.out.println(message);
}
} catch (IOException ioe) {
System.err.println("Connection to server broken.");
ioe.printStackTrace();
}
}
}
class Sender extends Thread
{
private PrintWriter mOut;
public Sender(PrintWriter aOut)
{
mOut = aOut;
}
/**
* Until interrupted reads messages from the standard input (keyboard)
* and sends them to the chat server through the socket.
*/
public void run()
{
try {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (!isInterrupted()) {
String message = in.readLine();
mOut.println(message);
mOut.flush();}} catch (IOException ioe) { // Communication is broken}}}