I have this class where i try to create a number of threads and then i need to send a message
to the server
over all the threads
or using a specific thread
. I can't seem to find a way to do that in this way I can only send using the last thread
that was created.
Here is the class:
public class test{
public test(){
}
public static void main(String[] args){
MultiThreadChatClient mc = new MultiThreadChatClient();
test st = new test();
for(int i =0; i<=4; i++){
mc.createThreads();
}
while (true) {
System.out.print("type your message: ");
Scanner s = new Scanner(System.in);
String ss = s.nextLine();
ss = ss.trim().replaceAll(" +", " ");
mc.sendMessage(ss);
try
{
Thread.sleep(400);
}
catch(InterruptedException e)
{
// this part is executed when an exception (in this example InterruptedException) occurs
System.out.println("Exeption: " + e);
}
}
}
}
Here's the Client thread class:
public class MultiThreadChatClient implements Runnable {
// The client socket
private static Socket clientSocket = null;
// The output stream
private static PrintStream os = null;
// The input stream
private static BufferedReader br;
private static BufferedReader inputLine = null;
private static boolean closed = false;
public static void main(String[] args) {
// The default port.
int portNumber = 2222;
// The default host.
String host = "localhost";
if (args.length < 2) {
System.out.println("Usage: java MultiThreadChatClient <host> <portNumber>\n"
+ "Now using host=" + host + ", portNumber=" + portNumber);
} else {
host = args[0];
portNumber = Integer.valueOf(args[1]).intValue();
}
}
/*
* Open a socket on a given host and port. Open input and output streams.
*/
public void createThreads(){
try {
clientSocket = new Socket("localhost", 2222);
inputLine = new BufferedReader(new InputStreamReader(System.in));
os = new PrintStream(clientSocket.getOutputStream());
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + 2222);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to the host " + 2222);
}
//}
/*
* If everything has been initialized then we want to write some data to the
* socket we have opened a connection to on the port portNumber.
*/
if (clientSocket != null && os != null && br != null) {
new Thread(new MultiThreadChatClient()).start();
}
}
public void sendMessage(String mes){
os.println(mes);
}
/*
* Create a thread to read from the server. (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
/*
* Keep on reading from the socket till we receive "Bye" from the
* server. Once we received that then we want to break.
*/
String responseLine;
try {
while ((responseLine = br.readLine()) != null){
System.out.println(responseLine);
if (responseLine.indexOf("*** Bye") != -1)
break;
}
closed = true;
} catch (IOException e) {
System.err.println("IOException1234: " + e);
}
}
}
Here's the server code:
public class MultiThreadChatServerSync {
// The server socket.
private static ServerSocket serverSocket = null;
// The client socket.
private static Socket clientSocket = null;
// This chat server can accept up to maxClientsCount clients' connections.
private static final int maxClientsCount = 50;
private static final clientThread[] threads = new clientThread[maxClientsCount];
public static void main(String args[]) {
// The default port number.
int portNumber = 2222;
if (args.length < 1) {
System.out.println("Usage: java MultiThreadChatServerSync <portNumber>\n"
+ "Now using port number=" + portNumber);
} else {
portNumber = Integer.valueOf(args[0]).intValue();
}
/*
* Open a server socket on the portNumber (default 2222). Note that we can
* not choose a port less than 1023 if we are not privileged users (root).
*/
try {
serverSocket = new ServerSocket(portNumber);
//System.out.println(serverSocket.getPort());
} catch (IOException e) {
System.out.println(e);
}
/*
* Create a client socket for each connection and pass it to a new client
* thread.
*/
while (true) {
try {
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++) {
if (threads[i] == null) {
(threads[i] = new clientThread(clientSocket, threads)).start();
//System.out.println("A new client is created");
break;
}
}
if (i == maxClientsCount) {
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
}
class clientThread extends Thread {
MultiThreadChatServerSync ms = new MultiThreadChatServerSync();
private String clientName = null;
//private DataInputStream is = null;
private BufferedReader br = null;
private PrintStream os = null;
private Socket clientSocket = null;
private final clientThread[] threads;
private int maxClientsCount;
public clientThread(Socket clientSocket, clientThread[] threads) {
this.clientSocket = clientSocket;
this.threads = threads;
maxClientsCount = threads.length;
//System.out.println("Inside the Client thread");
}
public void run() {
MultiThreadChatServerSync mss = new MultiThreadChatServerSync();
int maxClientsCount = this.maxClientsCount;
clientThread[] threads = this.threads;
//System.out.println("Inside the run");
try {
/*
* Create input and output streams for this client.
*/
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
while (true) {
String line = br.readLine();
System.out.println("message received via Client port: " + clientSocket.getPort());
System.out.println("Received: " + line);
}
} catch (IOException e) {
}
}
}
So, is there a way to create 5 threads and then send the message over all of them or choose one specific thread out of them?
To be able to have a client which starts several sessions, and to be able to send data to one or several of them, the client must change in a few ways.
The code is based on your original code, and meant to be a template for further enhancements: It will manage 5 client sessions, and be able to write to 1 or many.
The new main Thread (As an example, the Scanner will first ask the message for client #1, then 2, 3, 4 and next will broadcast to all, in a loop):
public class MultiThreadChatClientRunner {
final int NO_CLIENTS = 5;
//final String HOST_IP = "192.168.2.7";
final String HOST_IP = "localhost";
public static void main(String[] args) {
new MultiThreadChatClientRunner().start();
}
private void start() {
Socket[] sockets = new Socket[NO_CLIENTS];
PrintStream[] writers = new PrintStream[NO_CLIENTS];
BufferedReader[] readers = new BufferedReader[NO_CLIENTS];
for (int i = 0; i < NO_CLIENTS; i++) {
System.out.println("Creating client number "+i);
Socket clientSocket;
try {
clientSocket = new Socket(HOST_IP, 2222);
writers[i] = new PrintStream(clientSocket.getOutputStream());
readers[i] = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
new Thread(new MultiThreadChatClient(i, readers[i])).start();
} catch (IOException e) {
e.printStackTrace();
}
}
int clientId = 0;
Scanner s = new Scanner(System.in);
while (true) {
System.out.print("type your message for client #"+clientId);
String ss = s.nextLine();
ss = ss.trim().replaceAll(" +", " ");
writers[clientId].println(ss);
clientId = (clientId+1)%NO_CLIENTS;
// Test to broadcast to all clients
if (clientId == 4) {
for (int i = 0; i<NO_CLIENTS; i++)
writers[i].println("Broadcast message: "+ss);
}
try {
Thread.sleep(400);
} catch (InterruptedException e) {
System.out.println("Thread was interrupted");
break;
}
}
s.close();
}
}
The new client, which is much simpler than before:
public class MultiThreadChatClient implements Runnable {
// The client socket
private Socket clientSocket = null;
// The output stream
private PrintStream os = null;
// The input stream
private final BufferedReader br;
private final int clientId;
public MultiThreadChatClient(int clientId, BufferedReader br) {
super();
this.clientId = clientId;
this.br = br;
}
/*
* Create a thread to read from the server. (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
public void run() {
/*
* Keep on reading from the socket till we receive "Bye" from the
* server. Once we received that then we want to break.
*/
String responseLine;
try {
while ((responseLine = br.readLine()) != null) {
System.out.printf("Client #%d received message=%s\n", clientId, responseLine);
if (responseLine.indexOf("*** Bye") != -1)
break;
}
} catch (IOException e) {
System.err.println("IOException1234: " + e);
}
}
}
And the server, which is nearly identical, but manages closes better, and has some more logging to show which client is communicating.
public class MultiThreadChatServerSync {
// The server socket.
private static ServerSocket serverSocket = null;
// The client socket.
private static Socket clientSocket = null;
// This chat server can accept up to maxClientsCount clients' connections.
private static final int maxClientsCount = 50;
private static final ClientThread[] threads = new ClientThread[maxClientsCount];
public static void main(String args[]) {
// The default port number.
int portNumber = 2222;
if (args.length < 1) {
System.out.println(
"Usage: java MultiThreadChatServerSync <portNumber>\n" + "Now using port number=" + portNumber);
} else {
portNumber = Integer.valueOf(args[0]).intValue();
}
/*
* Open a server socket on the portNumber (default 2222). Note that we
* can not choose a port less than 1023 if we are not privileged users
* (root).
*/
try {
serverSocket = new ServerSocket(portNumber);
// System.out.println(serverSocket.getPort());
} catch (IOException e) {
System.out.println(e);
}
/*
* Create a client socket for each connection and pass it to a new
* client thread.
*/
while (true) {
try {
System.out.println("Awaiting a new connection on "+serverSocket.getLocalPort());
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++) {
if (threads[i] == null) {
(threads[i] = new ClientThread(i, clientSocket)).start();
// System.out.println("A new client is created");
break;
}
}
if (i == maxClientsCount) {
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
}
class ClientThread extends Thread {
private BufferedReader br = null;
private PrintStream os = null;
private final Socket clientSocket;
private final int clientId;
public ClientThread(int clientId, Socket clientSocket) {
this.clientSocket = clientSocket;
this.clientId = clientId;
}
public void run() {
try {
/*
* Create input and output streams for this client.
*/
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
String line = "";
while ((line = br.readLine()) != null) {
System.out.printf("Client <%d> received message=<%s> via Client port: <%d>\n", clientId, line, clientSocket.getPort());
// Echo it back (as a test)
os.println(line);
}
br.close();
os.close();
clientSocket.close();
} catch (IOException e) {
}
System.out.println("Client has closed the session");
}
}
Let me know if you have any further questions at this time.