5

I am building a small chat application in which client A wants to send something to client C with server B in between. First of all is this a correct approach for the problem??. I am able to send and receive data to and from a server but it is limited to only the client.For example if Client A sends data to server B and client C is sending data to server B then i can send data back to A and C just like an echo server. But what i want is to forward data coming from Client A to Client C via server B.

The following is the server code:

public class Server { public static void main(String[] args) { int port = 666; //random port number try { ServerSocket ss = new ServerSocket(port); System.out.println("Waiting for a client...."); System.out.println("Got a client :) ... Finally, someone saw me through all the cover!"); System.out.println(); while(true) { Socket socket = ss.accept(); SSocket sSocket = new SSocket(socket); Thread t = new Thread(sSocket); t.start(); System.out.println("Socket Stack Size-----"+socketMap.size()); } } catch (Exception e) { } } } class SSocket implements Runnable { private Socket socket; public SSocket(Socket socket) { this.socket = socket; } @Override public void run() { try { InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); DataInputStream dIn = new DataInputStream(in); DataOutputStream dOut = new DataOutputStream(out); String line = null; while (true) { line = dIn.readUTF(); System.out.println("Recievd the line----" + line); dOut.writeUTF(line + " Comming back from the server"); dOut.flush(); System.out.println("waiting for the next line...."); } } catch (Exception e) { } } } 

The client code is :

public class Client { public static void main(String[] args) { int serverPort = 666; try { InetAddress inetAdd = InetAddress.getByName("127.0.0.1"); Socket socket = new Socket(inetAdd, serverPort); InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); DataInputStream dIn = new DataInputStream(in); DataOutputStream dOut = new DataOutputStream(out); BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Type in something and press enter. Will send it to the server and tell ya what it thinks."); System.out.println(); String line = null; while (true) { line = keyboard.readLine(); System.out.println("Wrinting Something on the server"); dOut.writeUTF(line); dOut.flush(); line = dIn.readUTF(); System.out.println("Line Sent back by the server---" + line); } } catch (Exception e) { } } } 

3 Answers 3

5

When your clients connect to the server, your server creates a Socket for it, here it is Socket socket = ss.accept();, your socket variable will be holding that client.

now if you just keep adding your client socket to a arraylist in your while loop, you will have a list of clients actively connected with your server like:

after the accept:

clients = new ArrayList<DataOutputStream>(); Socket socket = ss.accept(); os = new DataOutputStream(socket.getOutputStream()); clients.add(os); 

Now as you have all the clients in that clients arraylist, you can loop through it, or with some protocol define which client should i send the data after reading.

Iterator<DataOutputStream> it = clients.iterator(); while ((message = reader.readLine()) != null) { //reading while (it.hasNext()) { try { DataOutputStream oss = it.next(); oss.write(message);//writing oss.flush(); } catch (Exception e) { } } } 

This will loop through all the available clients in the arraylist and will send to all. you can define ways to send to only some.

For example: maintain a ActiveClients arraylist and with some GUI interaction may be or maybe, define what all clients you want to send the message. Then add just those clients outputStreams to ActiveClients

ActiveClients.add(clients.get(2)); 

or remove them, if you don't want them.

ActiveClients.remove(clients.get(2)); 

and now just loop through this arraylist to send the data as above.

Sign up to request clarification or add additional context in comments.

Comments

1

You can create message queue for each client:

  1. Client A sends message 'Hi' with address Client C to server B.
  2. Server B receives message and adds it to message queue of client C.
  3. Thread in server B which communicates with client C check message queue, retrieve message and sends it to client C.
  4. Client C receives message.

Comments

0

If I am not mistaken, you must be having a problem with receiving a message from the Server or SSocket class. What happens with your code is that when you send a message from the client to the server the Server class receives your messages also gives an echo of the message in the client. However, when you send a message from the Server class, you don't get any messages in the Client Class.

To get this to work, you would have to modify your code in the following fashion:

SSocket Class

String line = null; while (true) { line = dIn.readUTF(); System.out.println("Recievd the line----" + line); dOut.writeUTF(line + " Comming back from the server"); dOut.flush(); System.out.println("waiting for the next line...."); } 

You should add these lines:

String Line2 = take.nextLine(); //The user types a message for the client dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client 

Replace the while loop with this one and it will work fine.

while (true) { line = dIn.readUTF(); //Takes the msg from the client System.out.println("Recievd the line----" + line); //Prints the taken message String Line2 = take.nextLine(); //The user types a message for the client dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client dOut.flush(); System.out.println("waiting for the next line...."); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.