Chat Application Java
Chat Application Java
Name: B.Anuhya
Reg.no-18MIS0394
Chat application:
The application consists of two parts: server and client. Each part can run independently on
separate computers.
package net.codejava.networking.chat.server;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* This is the chat server program.
* Press Ctrl + C to terminate the program.
*
* @author www.codejava.net
*/
public class ChatServer {
private int port;
private Set<String> userNames = new HashSet<>();
private Set<UserThread> userThreads = new HashSet<>();
/**
* Delivers a message from one user to others (broadcasting)
*/
void broadcast(String message, UserThread excludeUser) {
for (UserThread aUser : userThreads) {
if (aUser != excludeUser) {
aUser.sendMessage(message);
}
}
}
/**
* Stores username of the newly connected client.
*/
void addUserName(String userName) {
userNames.add(userName);
}
/**
* When a client is disconneted, removes the associated username and UserThread
*/
void removeUser(String userName, UserThread aUser) {
boolean removed = userNames.remove(userName);
if (removed) {
userThreads.remove(aUser);
System.out.println("The user " + userName + " quitted");
}
}
Set<String> getUserNames() {
return this.userNames;
}
/**
* Returns true if there are other users connected (not count the currently connected user)
*/
boolean hasUsers() {
return !this.userNames.isEmpty();
}
}
As you can see, the ChatServer class has two Set collections to keep track the names and
threads of the connected clients. Set is used because it doesn’t allow duplication and the order
of elements does not matter:
An important method in the ChatServer class is broadcast() which deliver a message from
one client to all others clients:
The UserThread class is responsible for reading messages sent from the client and
broadcasting messages to all other clients. First, it sends a list of online users to the new user.
Then it reads the username and notifies other users about the new user.
The following code is of the UserThread class:
package net.codejava.networking.chat.server;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* This thread handles connection for each connected client, so the server
* can handle multiple clients at the same time.
*
* @author www.codejava.net
*/
public class UserThread extends Thread {
private Socket socket;
private ChatServer server;
private PrintWriter writer;
printUsers();
String clientMessage;
do {
clientMessage = reader.readLine();
serverMessage = "[" + userName + "]: " + clientMessage;
server.broadcast(serverMessage, this);
} while (!clientMessage.equals("bye"));
server.removeUser(userName, this);
socket.close();
/**
* Sends a list of online users to the newly connected user.
*/
void printUsers() {
if (server.hasUsers()) {
writer.println("Connected users: " + server.getUserNames());
} else {
writer.println("No other users connected");
}
}
/**
* Sends a message to the client.
*/
void sendMessage(String message) {
writer.println(message);
}
}
Then it enters a loop of reading message from the user and sending it to all other users, until
the user sends ‘bye’ indicating he or she is going to quit. And finally it notifies other users
about the disconnection of this user and closes the connection.
package net.codejava.networking.chat.client;
import java.net.*;
import java.io.*;
/**
* This is the chat client program.
* Type 'bye' to terminte the program.
*
* @author www.codejava.net
*/
public class ChatClient {
private String hostname;
private int port;
private String userName;
String getUserName() {
return this.userName;
}
The ReadThread is responsible for reading input from the server and printing it to the console
repeatedly, until the client disconnects. This class is implemented as follows:
package net.codejava.networking.chat.client;
import java.io.*;
import java.net.*;
/**
* This thread is responsible for reading server's input and printing it
* to the console.
* It runs in an infinite loop until the client disconnects from the server.
*
* @author www.codejava.net
*/
public class ReadThread extends Thread {
private BufferedReader reader;
private Socket socket;
private ChatClient client;
try {
InputStream input = socket.getInputStream();
reader = new BufferedReader(new InputStreamReader(input));
} catch (IOException ex) {
System.out.println("Error getting input stream: " + ex.getMessage());
ex.printStackTrace();
}
}
package net.codejava.networking.chat.client;
import java.io.*;
import java.net.*;
/**
* This thread is responsible for reading user's input and send it
* to the server.
* It runs in an infinite loop until the user types 'bye' to quit.
*
* @author www.codejava.net
*/
public class WriteThread extends Thread {
private PrintWriter writer;
private Socket socket;
private ChatClient client;
try {
OutputStream output = socket.getOutputStream();
writer = new PrintWriter(output, true);
} catch (IOException ex) {
System.out.println("Error getting output stream: " + ex.getMessage());
ex.printStackTrace();
}
}
String text;
do {
text = console.readLine("[" + userName + "]: ");
writer.println(text);
} while (!text.equals("bye"));
try {
socket.close();
} catch (IOException ex) {
The reasons for running these two threads simultaneously is that the reading operation always
blocks the current thread (both reading user’s input from command line and reading server’s
input via network). That means if the current thread is waiting for the user’s input, it can’t
read input from the server.
Therefore, two separate threads are used to make the client responsive: it can display
messages from other users while reading message from the current user.