-1

my server only needs to send message to all clients. This question has been asked numerous times and the solution is to create an arraylist and to send to all just iterate over it calling the required method

i took the server example found at link here

quoted below

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MultiThreadServer implements Runnable {
   Socket csocket;
   MultiThreadServer(Socket csocket) {
      this.csocket = csocket;
   }
   public static void main(String args[]) throws Exception { 
      ServerSocket ssock = new ServerSocket(1234);
      System.out.println("Listening");

      while (true) {
         Socket sock = ssock.accept();
         System.out.println("Connected");
         new Thread(new MultiThreadServer(sock)).start();
      }
   }
   public void run() {
      try {
         PrintStream pstream = new PrintStream(csocket.getOutputStream());
         for (int i = 100; i >= 0; i--) {
            pstream.println(i + " bottles of beer on the wall");
         }
         pstream.close();
         csocket.close();
      } catch (IOException e) {
         System.out.println(e);
      }
   }
}

just i changed the code in run() to

   boolean running = true;
   public void run() {
   while(running){

       try {
           InputStream inFromCli = csocket.getInputStream();
           DataOutputStream out = new DataOutputStream(csocket.getOutputStream());
           conns.add(out);
           DataInputStream in = new DataInputStream(inFromCli);
           String inMsg = in.readUTF();
           String[] words= inMsg.split(" ");
           if(".sendall".equals(words[0])){
               for(DataOutputStream elem : conns){
                   elem.writeUTF("tgthrt");
                   elem.flush();

                 }
           }
     } catch (IOException e) {
          running= false;
     }
   }
}

where conns is an arrayList defined thus :

ArrayList<DataOutputStream> conns = new ArrayList<>();

however, when i iterate, it does not send to all clients. How can i modify it?

Palm Tree
  • 54
  • 12

1 Answers1

1

The thread is running the ssock.accept() which waits for a connection therefore your loop is never reached until a connection is opened.

I suggest creating a separate thread for handling the connected Sockets and using something like a Timer to reopen connections when clients want to connect.

Something like this could work:

private static ArrayList<Timer> listeners = new ArrayList<Timer>();

public static void createSocketListener(CustomSocket s) {
    listeners.add(new Timer());
    listeners.get(listeners.size() -1).scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            // your code logic
        }
    }, 1000, 1000);
}

The CustomSocket will hold the instanced DataInputStream and DataOutputStream corresponding to the Socket. You can simply keep checking for a new input through this thread on multiple clients and handle the request.

It can be used simply by doing something like:

Timer serverConnection = new Timer();
serverConnection.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        SomeThread.createSocketListener(ssock.accept());
    }
}, 1000, 1000);
Jaquarh
  • 6,493
  • 7
  • 34
  • 86
  • thank you, my loop is reached and the message is sent, however to only one client ! – Palm Tree Sep 08 '17 at 08:19
  • Are you looping correctly? ie `for(DataOutputStream os : conns) { // logic }` - I still think the `accept()` is breaking the loop though – Jaquarh Sep 08 '17 at 08:21
  • https://stackoverflow.com/questions/12550712/ive-created-a-java-server-with-sockets-just-how-do-print-to-all-sockets - how do i implement it for me? – Palm Tree Sep 08 '17 at 08:26