2012-09-23 6 views
6

Ich habe es schon eine Weile versucht und möchte, dass mehrere Clients gleichzeitig mehrere Eingänge empfangen.
Es gibt ein Problem, ich möchte, dass der Server "Hi" an alle Clients ausgibt, wenn ein Client "print2all Hi" sagt.
Ich weiß, wie man es verarbeitet, um es zu drucken, nur um auf alle Clients zu drucken, ist das Problem.Ich habe einen Java-Server mit Sockets erstellt, wie funktioniert das Drucken auf ALL-Sockets?

Hier ist, was ich bisher habe.
Server

try{ 
    try{ 
     server = new ServerSocket(25565); 
    } catch (Exception e){ 
     e.printStackTrace(); 
    } 
    while (isListening){ 
     new SocketThread(server.accept()).start(); 
    } 
    server.close(); 
} catch (Exception e){ 
    e.printStackTrace(); 
} 

SocketThread

try { 
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

    String inputLine, outputLine; 
    Processor kkp = new Processor(); 
    out.println("Hi!"); 

    while ((inputLine = in.readLine()) != null) { 
     outputLine = kkp.Proccess(inputLine,this.socket); 
     out.println(outputLine); 
    } 
    out.close(); 
    in.close(); 
    socket.close(); 

} catch (IOException e) { 
    e.printStackTrace(); 
} 

Kunde

  Processor p = new Processor(); 
      socket = new Socket("localhost",25565); 
      out = new PrintWriter(socket.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
  BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
      String fromServer; 
      String fromUser; 

      out.println("print2all Hi") 

      socket.close(); 

Jungs. Wenn Sie dies als Starter-Server verwenden möchten, gebe ich volle Erlaubnis = P

Antwort

5

Zuerst Sie den Überblick über alle angeschlossenen Kunden halten müssen:

final List<SocketThread> clients = new ArrayList<>(); 

while (isListening){ 
    SocketThread client = new SocketThread(server.accept()).start(); 
    clients.add(client); 
} 

solche Liste zu haben, wenn ein Client "print2all Hi" erhält es einfach iteriert über alle clients und sendet Nachricht an jede von ihnen. Um dies zu tun, müssen Sie wahrscheinlich eine Methode auf SocketThread verfügbar machen, die auf Client-Socket zugreifen wird. Das bedeutet, dass Sie die Variable out in Feld ändern müssen.

Alternative Vorgehensweise besteht darin, eine Liste der Client-Sockets zu führen. Dies bricht jedoch die Kapselung stark. Sie könnten auch in böse IO/Thread-Sicherheitsprobleme stoßen, wenn Sockets direkt ausgesetzt sind. Verstecken Sie sie besser hinter einer API (wie SocketThread Methode) und machen Sie die Synchronisation richtig in.

+1

Ich glaube nicht, dass Steckdosen obwohl Thread-sicher sind, so dass Sie bei gleichzeitigem Druck aus der Steckdose Gewinden besitzen die Buchse könnten am Ende und die eine Sendung. –

+0

@ChristopheBiocca: Sie haben Recht, aber OP scheint viel einfachere Probleme zu haben. Aber ich werde über Fadensicherheit erwähnen, danke! –

+0

+1 Wenn Sie eine Sammlung aus der Concurrency-Bibliothek verwenden, können Sie den Thread hinzufügen und schließlich den Socket entfernen, um die Liste zu verwalten. Wahrscheinlich ist das Hinzufügen und Entfernen des Handlers der Verbindung nützlicher, da Sie den Zustand der Verbindungen gut erkennen können. –

1

Eine vollständige Implementierung dessen, was Sie suchen.

Server

package tcpserver; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.StringTokenizer; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class TCPServer { 

    private int serverPort = 25565; 
    private ServerSocket serverSocket; 
    private List<ConnectionService> connections = new ArrayList<ConnectionService>(); 

    public TCPServer() { 
     try { 
      serverSocket = new ServerSocket(serverPort); 
      System.out.println("Waiting..."); 
      while (true) { 
       Socket socket = serverSocket.accept(); 
       System.out.println("Connected: " + socket); 
       ConnectionService service = new ConnectionService(socket); 
       service.start(); 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    public static void main(String[] args) { 
     new TCPServer(); 
    } 

    class ConnectionService extends Thread { 

     private Socket socket; 
     private BufferedReader inputReader; 
     private PrintWriter outputWriter; 
     //private String username; 

     public ConnectionService(Socket socket) { 
      this.socket = socket; 
      try { 
       inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       outputWriter = new PrintWriter(socket.getOutputStream(), true); 
      } catch (IOException e) { 
       System.out.println(e.getMessage()); 
      } 
     } 

     @Override 
     public void run() { 
      while (true) { 
       try { 
        String receivedMessage = inputReader.readLine(); 
        System.out.println(receivedMessage); 
        StringTokenizer stoken = new StringTokenizer(receivedMessage); 
        String fargument = stoken.nextToken(); 
        if (fargument.equals("print2all")) { 
         this.sendToAnyone(stoken.nextToken()); 
        } 
       } catch (IOException ex) { 
        Logger.getLogger(TCPServer.class.getName()).log(Level.SEVERE, null, ex); 
       } catch (NullPointerException e) { 
        System.out.println(e.getMessage()); 
       } finally { 
        outputWriter.close(); 
       } 

      } 
     } 

     protected void sendMessage(String message) { 
      outputWriter.println(message); 
     } 

     private void sendToAnyone(String message) { 

      for (ConnectionService connection : connections) { 
       connection.sendMessage(message); 
      } 
     } 
    } 
} 

Kunde

package tcpclient; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.Socket; 

public class tcpClient extends javax.swing.JFrame { 

    private Socket socket; 
    private BufferedReader inputReader; 
    private PrintWriter outputWriter; 

    public tcpClient() { 
     connectToServer(); 
    } 

    private void connectToServer() { 
     try { 
      socket = new Socket(InetAddress.getByName("localhost"), 25565); 
      inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      outputWriter = new PrintWriter(socket.getOutputStream(), true); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     new Thread() { 
      @Override 
      public void run() { 
       receiveData(); 
      } 
     }.start(); 
    } 

    private void receiveData() { 
     try { 
      while (true) { 
       System.out.println(inputReader.readLine()); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void sendData(String messageToSend) { 
     outputWriter.println(messageToSend); 
    } 

    public void closeSocket() { 
     if (socket != null) { 
      try { 
       socket.close(); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
     } 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       tcpClient client = new tcpClient(); 
       client.sendData("print2all Hi"); 
       client.closeSocket(); 
      } 
     }); 
    } 
} 
Verwandte Themen