Create a threaded chat server and a corresponding chat client Using java
Create a threaded chat server and a corresponding chat client. Using the port of
your choice, create a server that starts a new thread for every client that connects to
it. Every message that the server receives from a client should be broadcast back to
all other clients. The chat client should allow the user to type in a string of text and
have it sent to the server upon pressing enter. Use threads on the client so messages
can be retrieved from the server and displayed even while the user is typing. Test
your server by connecting to it with multiple clients and verifying that messages
are transmitted back and forth.
Answer:
/**
* This program implements a simple chat server. Every client that
* connects to the server can broadcast data to all other clients.
* The server stores an ArrayList of sockets to perform the broadcast.
*
* The code is set up so all clients and servers must be run on the same
* machine. That is easily changed by setting “localhost” to the desired hostname.
*
* To test, start the server first, then start multiple clients and type messages
* in the client windows.
*/
import java.net.ServerSocket;
import java.net.Socket;
import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
public class QuestionServer
{
// Maintain list of all client sockets for broadcast
private ArrayList<Socket> socketList;
public QuestionServer()
{
socketList = new ArrayList<Socket>();
}
private void getConnection()
{
// Wait for a connection from the client
try
{
System.out.println("Waiting for client connections on port 7654.");
ServerSocket serverSock = new ServerSocket(7654);
// This is an infinite loop, the user will have to shut it down
// using control-c
while (true)
{
Socket connectionSock = serverSock.accept();
// Add this socket to the list
socketList.add(connectionSock);
// Send to ClientHandler the socket and arraylist of all sockets
ClientHandler handler =
new ClientHandler(connectionSock, this.socketList);
Thread theThread = new Thread(handler);
theThread.start();
}
// Will never get here, but if the above loop is given
// an exit condition then we'll go ahead and close the socket
//serverSock.close();
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
public static void main(String[] args)
{
Question8Server server = new Question8Server();
server.getConnection();
}
}
/**
* ClientHandler.java
*
* This class handles communication between the client
* and the server. It runs in a separate thread but has a
* link to a common list of sockets to handle broadcast.
*/
import java.net.Socket;
import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.ArrayList;
public class ClientHandler implements Runnable
{
private Socket connectionSock = null;
private ArrayList<Socket> socketList;
ClientHandler(Socket sock, ArrayList<Socket> socketList)
{
this.connectionSock = sock;
this.socketList = socketList; // Keep reference to master list
}
public void run()
{
// Get data from a client and send it to everyone else
try
{
System.out.println("Connection made with socket " + connectionSock);
BufferedReader clientInput = new BufferedReader(
new InputStreamReader(connectionSock.getInputStream()));
while (true)
{
// Get data sent from a client
String clientText = clientInput.readLine();
if (clientText != null)
{
System.out.println("Received: " + clientText);
// Turn around and output this data
// to all other clients except the one
// that sent us this information
for (Socket s : socketList)
{
if (s != connectionSock)
{
DataOutputStream clientOutput =
new DataOutputStream(
s.getOutputStream());
clientOutput.writeBytes(clientText + "\n");
}
}
}
else
{
// Connection was lost
System.out.println("Closing connection for socket "
+ connectionSock);
// Remove from arraylist
socketList.remove(connectionSock);
connectionSock.close();
break;
}
}
}
catch (Exception e)
{
System.out.println("Error: " + e.toString());
// Remove from arraylist
socketList.remove(connectionSock);
}
}
}
/**
* This java program implements a simple chat client. It connects to the
* server (assumed to be localhost on port 7654) and starts two threads:
* one for listening for data sent from the server, and another that waits
* for the user to type something in that will be sent to the server.
* Anything sent to the server is broadcast to all clients.
*
* Data received is sent to the output screen, so it is possible that as
* a user is typing in information a message from the server will be
* inserted. This can be disconcerting - a better approach would be to
* use a GUI with separate windows or textareas for user input and
* messages sent by the server.
*/
import java.net.Socket;
import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Scanner;
public class QuestionClient
{
public static void main(String[] args)
{
try
{
String hostname = "localhost";
int port = 7654;
System.out.println("Connecting to server on port " + port);
Socket connectionSock = new Socket(hostname, port);
DataOutputStream serverOutput = new DataOutputStream(
connectionSock.getOutputStream());
System.out.println("Connection made.");
// Start a thread to listen and display data sent by the server
ClientListener listener = new ClientListener(connectionSock);
Thread theThread = new Thread(listener);
theThread.start();
// Read input from the keyboard and send it to everyone else.
// The only way to quit is to hit control-c, but a quit command
// could easily be added.
Scanner keyboard = new Scanner(System.in);
while (true)
{
String data = keyboard.nextLine();
serverOutput.writeBytes(data + "\n");
}
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}
/**
* ClientListener.java
*
* This class runs on the client end and just
* displays any text received from the server.
*/
import java.net.Socket;
import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Scanner;
import java.util.ArrayList;
public class ClientListener implements Runnable
{
private Socket connectionSock = null;
ClientListener(Socket sock)
{
this.connectionSock = sock;
}
public void run()
{
// Wait for data from the server. If received, output it.
try
{
BufferedReader serverInput = new BufferedReader(
new InputStreamReader(connectionSock.getInputStream()));
while (true)
{
// Get data sent from the server
String serverText = serverInput.readLine();
if (serverInput != null)
{
System.out.println(serverText);
}
else
{
// Connection was lost
System.out.println("Closing connection for socket " +
connectionSock);
connectionSock.close();
break;
}
}
}
catch (Exception e)
{
System.out.println("Error: " + e.toString());
}
}
Leave a reply