views:

62

answers:

3
+1  Q: 

Java Server Help!

I've followed a tutorial to create the socket server below which allows multiple users to connect and if they send some data to it then it returns it back to them.

   import java.awt.Color;
    import java.awt.BorderLayout;
    import java.awt.event.*;
    import javax.swing.*;

    import java.io.*;
    import java.net.*;

    class ClientWorker implements Runnable {
      private Socket client;
      private JTextArea textArea;

      ClientWorker(Socket client, JTextArea textArea) {
       this.client = client;
       this.textArea = textArea;   
      }

      public void run(){
        String line;
        BufferedReader in = null;
        PrintWriter out = null;
        try{
          in = new BufferedReader(new InputStreamReader(client.getInputStream()));
          out = new PrintWriter(client.getOutputStream(), true);
        } catch (IOException e) {
          System.out.println("in or out failed");
          System.exit(-1);
        }

        while(true){
          try{
            line = in.readLine();
    //Send data back to client
             out.println(line);
             textArea.append(line);
           } catch (IOException e) {
             System.out.println("Read failed");
             System.exit(-1);
           }
        }
      }
    }



----------


    class SocketThrdServer extends JFrame{

       JLabel label = new JLabel("Text received over socket:");
       JPanel panel;
       JTextArea textArea = new JTextArea();
       ServerSocket server = null;

       SocketThrdServer(){ //Begin Constructor
         panel = new JPanel();
         panel.setLayout(new BorderLayout());
         panel.setBackground(Color.white);
         getContentPane().add(panel);
         panel.add("North", label);
         panel.add("Center", textArea);
       } //End Constructor

      public void listenSocket(){
        try{
          server = new ServerSocket(4444); 
        } catch (IOException e) {
          System.out.println("Could not listen on port 4444");
          System.exit(-1);
        }
        while(true){
          ClientWorker w;
          try{
            w = new ClientWorker(server.accept(), textArea);
            Thread t = new Thread(w);
            t.start();
          } catch (IOException e) {
            System.out.println("Accept failed: 4444");
            System.exit(-1);
          }
        }
      }

      protected void finalize(){
    //Objects created in run method are finalized when 
    //program terminates and thread exits
         try{
            server.close();
        } catch (IOException e) {
            System.out.println("Could not close socket");
            System.exit(-1);
        }
      }

      public static void main(String[] args){
            SocketThrdServer frame = new SocketThrdServer();
        frame.setTitle("Server Program");
            WindowListener l = new WindowAdapter() {
                    public void windowClosing(WindowEvent e) {
                            System.exit(0);
                    }
            };
            frame.addWindowListener(l);
            frame.pack();
            frame.setVisible(true);
            frame.listenSocket();
      }
    }

However I need it so if data is sent to the server rather than simply returning it, it sends it to everyone who is connected to the server. If someone helps me sort this out then ill be forever thankful! It means ill be able to finish my School project!

Thanks in advance :)

+3  A: 

Well... where shall I start? First of all you might want to have a look at dynamic structures like arrays or lists. Then you should handle each new client request so that the client is handed to a thread and then added to a list (in listenSocket()). Then whenever new data arrives the server should iterate over the list and dispatch the data to every thread/client (in your main loop).

Manrico Corazzi
+1  A: 

You need to keep track of all your client connections in a data structure such as a List. Then when the server receives input, it should loop through all the client connections and output the message it received.

Kaleb Brasee
+2  A: 

This is your problem:

//Send data back to client
out.println(line);

As the others have said, use a List to keep track of all your clients. Specifically, you want a List of ClientWorkers.

I use a simple Singleton class that keeps the List. This is so that when a new client connects it will add itself to the list and the other clients don't need to do anything to see that there is a new client. And add a method like writeString(String) to the ClientWorker class to make it easier to write something out to each client.

You should have a really basic loop like this in ClientWorker:

String line = in.readLine();
LinkedList<ClientWorkers> clients = SingletonClients.getClients();
for(int = 0; i < clients.size(); i++) {
    ClientWorker c = clients.get(i);
    //The client doesn't need to get it's own data back.
    if(c == this)
        continue;

    c.writeString(line);
}

writeString will just be:

public void writeString(String s) {
    try {
        out.println(s);
    } catch(IOException ex) {
    }
}
jonescb
Perfect! The only thing I'm a bit confused about is the singleton class. Could you maybe elaborate on this? Cheers :D
I don't feel like explaining the Singleton, but Wikipedia has information about it, and it has an example for Java. http://en.wikipedia.org/wiki/Singleton_pattern
jonescb