Chat-Server mit mehreren Threads

Ich bin neu in Threads. Ich versuche, Nachricht vom Server an Clients zu übertragen. Aber ich kann nicht. Es sieht so aus, als ob der Server immer auf eine neue Verbindung hört. Aber ich kann Nachrichten an andere Clients senden, die das Client-Terminal benutzen. Meine Frage ist, wie man während des Zuhörens gleichzeitig Eingaben zulässt. Hier ist der Code.

MultiThreadChatServerSync.java

import java.io.InputStreamReader; import java.io.DataInputStream; import java.io.PrintStream; import java.io.IOException; import java.net.Socket; import java.net.ServerSocket; import java.io.BufferedReader; public class MultiThreadChatServerSync extends Thread { private static ServerSocket serverSocket = null; private static Socket clientSocket = null; private static Socket serversSocket = null; private static DataInputStream iss = null; private static PrintStream oss = null; private static final int maxClientsCount = 10; private static final clientThread[] threads = new clientThread[maxClientsCount]; public static void main(String args[]) { int num = 0; int portNumber = 2222; if (args.length < 1) { System.out.println("Usage: java MultiThreadChatServerSync "Nowusingnumber=" + portNumber); } else { portNumber = Integer.valueOf(args[0]).intValue(); } try { serverSocket = new ServerSocket(portNumber); } catch (IOException e) { System.out.println(e); } DataInputStream iss = null; while (true) { try { System.out.println("5"); num++; // I want to be able to input text here to the server which will be // send to different clients // But I cannot clientSocket = serverSocket.accept(); int i = 0; for (i = 0; i < maxClientsCount; i++) { if (threads[i] == null) { System.out.println("6"); (threads[i] = new clientThread(clientSocket, threads)) .start(); break; } } if (i == maxClientsCount) { PrintStream os = new PrintStream(clientSocket.getOutputStream()); os.println("Server too busy. Try later."); os.close(); clientSocket.close(); } } catch (IOException e) { System.out.println(e); } } } } class clientThread extends Thread { private String clientName = null; private DataInputStream is = null; private PrintStream os = null; private Socket clientSocket = null; private final clientThread[] threads; private int maxClientsCount; public clientThread(Socket clientSocket, clientThread[] threads) { this.clientSocket = clientSocket; this.threads = threads; maxClientsCount = threads.length; } public void run() { int maxClientsCount = this.maxClientsCount; clientThread[] threads = this.threads; try { is = new DataInputStream(clientSocket.getInputStream()); os = new PrintStream(clientSocket.getOutputStream()); String name; while (true) { os.println("Enter your name."); name = is.readLine().trim(); if (name.indexOf('@') == -1) { break; } else { os.println("The name should not contain '@' character."); } } os.println("Welcome " + name + " to our chat room.\nTo leave enter /quit in a new line."); synchronized (this) { for (int i = 0; i < maxClientsCount; i++) { if (threads[i] != null && threads[i] == this) { clientName = "@" + name; break; } } for (int i = 0; i  1 && words[1] != null) { words[1] = words[1].trim(); if (!words[1].isEmpty()) { synchronized (this) { for (int i = 0; i < maxClientsCount; i++) { if (threads[i] != null && threads[i] != this && threads[i].clientName != null && threads[i].clientName.equals(words[0])) { threads[i].os.println(" " + words[1]); this.os.println(">" + name + "> " + words[1]); break; } } } } } } else { synchronized (this) { for (int i = 0; i < maxClientsCount; i++) { if (threads[i] != null && threads[i].clientName != null) { threads[i].os.println(" " + line); } } } } } synchronized (this) { for (int i = 0; i < maxClientsCount; i++) { if (threads[i] != null && threads[i] != this && threads[i].clientName != null) { threads[i].os.println("*** The user " + name + " is leaving the chat room !!! ***"); } } } os.println("*** Bye " + name + " ***"); synchronized (this) { for (int i = 0; i < maxClientsCount; i++) { if (threads[i] == this) { threads[i] = null; } } } is.close(); os.close(); clientSocket.close(); } catch (IOException e) { } } } 

  1. Sie sollten in einem Hintergrundthread auf Clients warten. Ihr Code tut dies derzeit nicht und so ist Ihr Server tatsächlich in einer endlosen while (true) Schleife eingeschlossen.
  2. Sie sollten Ihren Code umgestalten, damit Ihre Methoden nicht so groß und unhandlich sind.
  3. Sie sollten Ihren Code so umgestalten, dass Ihre Hauptmethode sehr kurz ist, sodass die Uhr einfach aufgezogen wird und sozusagen gestartet wird.
  4. Ihr Code als formatiert ist sehr schwer zu lesen. Bitte bedenken Sie, dass Sie Ihren Post bearbeiten und Ihren Eindruckstil so anpassen müssen, dass er einheitlich und konsistent ist. Normalerweise benutze ich Tabs zum Einrücken nicht (Forum-Software spielt oft nicht gut mit Tabs) und einrücken jeden Code Block 4 Leerzeichen.
  5. Sie möchten fast nie, dass Ihre class Thread erweitert. Implementieren Sie stattdessen Runnable (oder verwenden Sie Rod_Algonquins ausgezeichnete Empfehlung).
  6. Verwenden Sie keine veralteten Methoden wie DataInputStream#readLine(...) da dies gefährlich sein könnte.

Zum Beispiel könnte Ihre Hauptleitung so einfach sein wie diese …

 public static void main(String[] args) { MyServer myServer = new MyServer(); myServer.getThingsRunning(); } 

Bearbeiten
Hinweis, der als Warnung hinzugefügt wurde: Ich arbeite normalerweise nicht mit Sockets, Server-Sockets oder Chat-Programmen, und ich bin immer noch neu in der Verwendung von Executors, aber Sie könnten Ihren Code etwas in diese Richtung strukturieren …

 public class MultiServer implements Runnable { public static final int PORT_NUMBER = 2222; private static final int THREAD_POOL_COUNT = 20; private List clientList = new ArrayList<>(); private ServerSocket serverSocket; private ExecutorService clientExecutor = Executors.newFixedThreadPool(THREAD_POOL_COUNT); public MultiServer() throws IOException { serverSocket = new ServerSocket(PORT_NUMBER); } @Override public void run() { // embed your socket acceptance loop in a Runnable's run method while (true) { try { Socket clientSocket = serverSocket.accept(); MultiClient client = new MultiClient(clientSocket); clientList.add(client); clientExecutor.execute(client); } catch (IOException e) { // TODO notify someone of problem! e.printStackTrace(); } } } // ..... more methods and such public static void main(String[] args) { try { MultiServer multiServer = new MultiServer(); new Thread(multiServer).start(); } catch (IOException e) { e.printStackTrace(); } } }