2016-07-28 13 views
0

Ich baue eine Multithread-Chat-Server-Anwendung, die eine Nachricht von einem Client an alle Clients gesendet sendet.Auf den meisten Beispielen im Internet und auf Oracle-Website auch Broadcasting ist mit udp (Multicast Socket) gemacht, aber ich benutze tcp. Kann jemand eine Nachricht an alle verbundenen Clients in einer TCP-Verbindung senden? Hier ist meine aktuellen Code, der gut arbeitet und sendet die Nachricht von einem Client an diesem Client receieved nur:Wie man Nachrichten an alle Clients mit tcp in Java sendet

Echoserver

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

public class EchoServer 
{ 
    public static void main(String[] args) 
     throws IOException 
    { 
     if (args.length != 1) { 
      System.err.println("Usage: java EchoServer <port number>"); 
      System.exit(1); 
     } 

     int portNumber = Integer.parseInt(args[0]); 

     ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0])); 

     while (true) { 
      try { 
       Thread t = new Thread(new MultiServer(serverSocket.accept())); 
       t.start(); 
      } catch(IOException e) { 
       System.out.println("Accept Failed:"); 
       System.exit(-1); 
      } 
     } 
    } 
} 

Echoclient

import java.io.*; 
import java.util.Scanner; 
import java.net.*; 

public class EchoClient 
{ 
    public static void main(String[] args) throws IOException 
    { 
     if (args.length != 2) { 
      System.err.println("Usage: java EchoClient <host name><portnumber>"); 
      System.exit(1); 
     } 

     String hostName = "localhost"; 

     int portNumber = Integer.parseInt(args[1]); 

     try (
      Socket echoSocket = new Socket(hostName, portNumber); 
      PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true); 
      BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); 
      BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
     ) { 
      String userInput; 

      while ((userInput = stdIn.readLine()) != null) { 
       out.println(userInput); 
       System.out.println("echo::" + in.readLine()); 
      } 
     } catch (UnknownHostException e) { 
      System.err.println("Don't know about host " + hostName); 
      System.exit(1); 
     } catch (IOException e) { 
      System.err.println("Couldn't get I/O for the connection to " + hostName); 
      System.exit(1); 
     } 
    } 
} 

Multiserver

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

public class MultiServer implements Runnable 
{ 
    private Socket client; 

    public MultiServer(Socket m) 
    { 
     this.client = m; 
    } 

    @Override 
    public void run() 
    { 
     BufferedReader in = null; 
     PrintWriter out = null; 
     try { 
      out = new PrintWriter(client.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
     } catch(IOException ignored) { 
     } 

     while (true) { 
      String line; 
      try { 
       while ((line = in.readLine()) != null) 
        out.println(line); 
      } catch (IOException e) { 
       System.out.println("Read Failed"); 
       System.exit(-1); 
      } 
     } 
    } 
} 
+0

TCP unterstützt keine Broadcasts, ** aber ** Sie können einfach die gleiche Nachricht an jeden Client senden. – immibis

+0

Wie kann das gemacht werden? Können wir ArrayList verwenden? –

+0

Sie müssen eine eigene threadsichere Liste verbundener Clients verwalten und diese Liste dann immer dann durchlaufen, wenn Sie eine Broadcastnachricht senden müssen. Stellen Sie lediglich sicher, dass Ihr Kommunikationsprotokoll so konzipiert ist, dass unerwünschte Nachrichten jederzeit von Server zu Client gesendet werden und dass Sie jeden einzelnen Client thread-sicher senden, um sich überschneidende Nachrichten zu vermeiden, die von mehreren Threads gleichzeitig gesendet werden. Andernfalls werden Sie Ihre Kommunikation sehr leicht beschädigen. TCP-Broadcasting ist nicht einfach zu verwalten. –

Antwort

0

Verwenden Sie die gleichzeitige hashmap und pflegen Sie Ihre Liste der Clients in diesem. Die gleichzeitige hashmap ist sicher und Sie werden nicht beim Hinzufügen/Iterieren/Entfernen

// Create and main list of active clients based on their host name/ip address 
ConcurrentHashMap<String, Socket> activeClients = new ConcurrentHashMap<String, Socket>(); 

// message received 
activeClients.put(clientsocket.getInetAddress().getHostAddress(), clientsocket); 

// broadcast message to all available clients 
for(String clientHost : activeClients.keySet()) { 
     // get each socket here and send a message to them. 
} 

Vector ist im Grunde ein Thread-sicher ein verwenden Synchronisation benötigen, so müssen Sie über, dass man keine Sorge.

+0

Können Sie mir ein einfaches Beispiel dieser pls zeigen? –

+0

Momentan versuche ich die Klasse ** Vector ** zu verwenden, aber ich muss dort synchronisieren. Ist das nicht ein guter Ansatz? –