2017-10-03 1 views
-1

Screenshot des Programms läuft ein Fenster unter Verwendung von Steuer D/Z schließen (oben links: Server, der Rest sind Clients): enter image description hereWie ohne Verlassen des gesamten Programms (multithreaded Java-Buchse)

In der rechten unteren Fenster, ich versuche, Control D (Mac) zu drücken (für Windows ist es die Kontrolle Z), um das untere rechte Fenster/Client allein zu verlassen, ohne die gesamte Anwendung/Programm zu beenden, aber es scheint nicht zu arbeiten, weil ich kann immer noch "es hat nicht funktioniert" und es gibt die Nachricht aus.

Meine Frage ist: Welche Änderungen kann ich an den folgenden Code vornehmen, sodass, wenn ein Client Control D drückt, nur ein Fenster/Client geschlossen wird und die gesamte Anwendung nicht beendet wird?

Teil des Codes, der das Fenster (derzeit leer) schließen sollte:

  //This is the code that prints messages to all clients 
      synchronized (this) 
      { 
      for (int i = 0; i < maxClientsCount; i++) 
      { 
       if (!line.equals(null) && !line.equals("null") && !line.equals(null) && !line.equals("F") && !line.equals("m") && !line.equals("M") && threads[i] != null && threads[i].clientName != null && !threads[i].clientName.equals("m") && !threads[i].clientName.equals("M")) 
       { 
       if(!line.equals("") == true && line.isEmpty()== false) 
       { 

         threads[i].os.println(name + ": " + line); 
       } 

      } 
      //After Control D/Z is pressed, this code will execute 
       else if(line.equals(null) || line.equals("null") || line.contains("null")) 
       { 
        try 
        { 
         //This code location exits the program, system.exit(0) and system.exit(-1) didn't work 
         //how do i close only one client window here without exiting the whole program? 
        } 
        catch (NullPointerException ignored) 
        { 

        } 
        finally 
        { 

        } 
       // threads[i].os.close(); 
       // System.exit(0); 
       } 
      } 
      } 

HINWEIS: UM DEN REST SKIP und scrollen Sie nach unten, wenn Sie bereits die

Voll Code von ClientThreads.java Antwort kennen :

import java.io.*; 
import java.net.*; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.nio.file.StandardCopyOption; 
import java.util.*; 
import java.nio.*; 
import java.nio.channels.FileChannel; 
class ClientThreads extends Thread 
{ 
    public String path = ""; 
    public String name1 = ""; 
    private String clientName = null; 
    private DataInputStream is = null; 
    private PrintStream os = null; 
    private Socket clientSocket = null; 
    private final ClientThreads[] threads; 
    private int maxClientsCount; 
    public int position = 0; 
    public static List<String> listName = Collections.synchronizedList(new ArrayList<String>()); 
    List<String> l = Collections.synchronizedList(new ArrayList<String>()); 
    public String[] namesList = new String[10]; 
    public ClientThreads(Socket clientSocket, ClientThreads[] threads, 
      String name, String[] namesList, List<String> listName) 
    { 
    this.clientSocket = clientSocket; 
    this.threads = threads; 
    maxClientsCount = threads.length; 
    this.name1 = name; 
    this.namesList = namesList; 
    } 
@SuppressWarnings("deprecation") 
public void run() 
    { 
    int maxClientsCount = this.maxClientsCount; 
    ClientThreads[] threads = this.threads; 
    synchronized (listName) 
    { 
     //Iterator i = listName.iterator(); // Must be in synchronized block 

     ListIterator<String> i = listName.listIterator(); 
    } 
    try 
    { 
     is = new DataInputStream(clientSocket.getInputStream()); 
     os = new PrintStream(clientSocket.getOutputStream()); 
     String name; 
     String name3; 
     while (true) 
     { 
     //os.println("What is your name?"); 
     name = is.readLine().trim(); 
     name3 = name; 
     break; 
     } 
     synchronized(listName) 
     { 
     if(!listName.contains(name)) 
     { 
        if(!listName.contains(name) && name != null && !name.isEmpty()) 
        { 
         listName.add(name); 

         Path currentRelativePath = Paths.get(""); 
         path = currentRelativePath.toAbsolutePath().toString(); 
        } 
     } 

     } 
     synchronized (this) 
     { 
     for (int i = 0; i < maxClientsCount; i++) 
     { 
      if (threads[i] != null && threads[i] == this) 
      { 
      clientName = "@" + name; 
      break; 
      } 
     } 
     for (int i = 0; i < maxClientsCount; i++) 
     { 
      if (threads[i] != null) 
      { 

      } 
     } 
     } 
     while (true) 
     { 
     synchronized(listName) 
     { 
     } 
     String line = is.readLine(); 

     if (line.contains("3582938758912781739713asfaiwef;owjouruuzlxjcjnbbiewruwoerpqKFDJiuxo9")) 
     { 
      break; 
     } 
     else 
     { 
     } 
      synchronized (this) 
      { 
      for (int i = 0; i < maxClientsCount; i++) 
      { 
       if (!line.equals(null) && !line.equals("null") && !line.equals(null) && !line.equals("F") && !line.equals("m") && !line.equals("M") && threads[i] != null && threads[i].clientName != null && !threads[i].clientName.equals("m") && !threads[i].clientName.equals("M")) 
       { 
       if(!line.equals("") == true && line.isEmpty()== false) 
       { 

         threads[i].os.println(name + ": " + line); 
       } 

      } 
       else if(line.equals(null) || line.equals("null") || line.contains("null")) 
       { 
        try 
        { 
         //This code location exits the program, system.exit(0) and system.exit(-1) didn't work 
         //how do i close only one client window here without exiting the whole program? 
        } 
        catch (NullPointerException ignored) 
        { 

        } 
        finally 
        { 

        } 
       // threads[i].os.close(); 
       // System.exit(0); 
       } 
      } 
      } 
     // } 
     } 
     synchronized (this) 
     { 
     for (int i = 0; i < maxClientsCount; i++) 
     { 
      if (threads[i] != null && threads[i] != this && threads[i].clientName != null) 
      { 
      // threads[i].os.println(name + "has disconnected."); 
      threads[i].listName.remove(name); 
      listName.remove(name); 
      // threads[i].os.println("The list now contains: " + listName); 
      // System.out.println("A user disconnected. The list now contains: " +listName); 
      } 
     } 
     } 
     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) 
    { 
    } 
    } 


} 

Voll Code von ChatClient.java:

import java.io.*; 
import java.net.*; 
import java.nio.file.Path; 
import java.nio.file.Paths; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class ChatClient implements Runnable 
{ 
    public static String path = ""; 
    private static Socket clientSocket = null; 
    private static PrintStream os = null; 
    private static DataInputStream is = null; 
    private static BufferedReader inputLine = null; 
    private static boolean closed = false; 
    public static String[] namesList = new String[10]; 
    public int iteration = 0; 
    public static String[] responses = new String[50]; 
    public int responseCount = 0; 
    public static final int maxClientsCount = 10; 
    public static final ClientThreads[] threads = new ClientThreads[maxClientsCount]; 
    public static List<String> listName = Collections.synchronizedList(new ArrayList<String>()); 
    List<String> l = Collections.synchronizedList(new ArrayList<String>()); 
public ChatClient() 
{ 

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

    for(int i = 0; i < namesList.length; i++) 
    { 
     namesList[i] = ""; 
    } 
    for(int j = 0; j < responses.length; j++) 
    { 
     responses[j] = ""; 
    } 
    // System.out.println("args[0] is: " + args[0]); 
    int portNumber = Integer.valueOf(args[0]); 
    String host = "localhost"; 
    //int filePort = Integer.valueOf(args[0]); 
    try 
    { 

     synchronized(listName) 
     { 
      clientSocket = new Socket(host, portNumber); 
      inputLine = new BufferedReader(new InputStreamReader(System.in)); 
      os = new PrintStream(clientSocket.getOutputStream()); 
      is = new DataInputStream(clientSocket.getInputStream()); 
     } 

    } 
    catch (UnknownHostException e) 
    { 
     //System.err.println("Don't know about host " + host); 
    } catch (IOException e) 
    { 
    // System.err.println("Couldn't get I/O for the connection to the host " 
     // + host); 
    } 
    if (clientSocket != null && os != null && is != null) 
    { 
     try 
     { 

     new Thread(new ChatClient()).start(); 
     while (!closed) 
     { 
      os.println(inputLine.readLine()); 
     } 

     // os.close(); 
     //is.close(); 
     //clientSocket.close(); 

     } 
     catch (IOException e) 
     { 
     // System.err.println("IOException: " + e); 
     } 
    } 
    } 
@SuppressWarnings("deprecation") 
public void run() 
{ 
    String responseLine = ""; 
    try 
    { 
     while ((responseLine = is.readLine()) != null) 
     { 
      if(responseLine!=null && !responseLine.equals(null) && responseLine!="null" && !responseLine.equals("null") && !responseLine.contains("null")) 
     { 
       System.out.println(responseLine); 
     } 

     else if(responseLine.contains("null") || responseLine.equals("null") || responseLine==null || responseLine.equals(null)) 
     { 

      //This is another location which will be executed if Control D/Control Z is pressed 
      //os.close(); 
      // is.close(); 
      //System.exit(0); 
     } 


     } 
     //closed = true; 
    } 
    catch (IOException e) 
    { 
    // System.err.println("IOException: " + e); 
    } 
    } 
} 

Voll Code von ChatServer.java:

import java.io.*; 
import java.net.*; 
import java.util.*; 
public class ChatServer 
{ 
    public static List<String> listName = Collections.synchronizedList(new ArrayList<String>()); 
    List<String> l = Collections.synchronizedList(new ArrayList<String>()); 
    public static ServerSocket serverSocket = null; 
    public static Socket clientSocket = null; 
    public static final int maxClientsCount = 10; 
    public static final ClientThreads[] threads = new ClientThreads[maxClientsCount]; 
    public static String[] namesList = new String[10]; 
// public ChatClient arrayOfNames = new ChatClient; 


    public static void main(String args[]) 
    { 
     synchronized (listName) 
     { 
      //Iterator i = listName.iterator(); // Must be in synchronized block 

      Iterator<String> i = listName.listIterator(); 
     } 
     int once = 0; 
     if(once == 0) 
     { 
     // System.out.println("args[0] is: " + args[0]); 
      int portNumber = Integer.valueOf(args[0]); 
     // System.out.println("waiting for connections on port " + portNumber + " ...\n "); 
      once = 3; 
     } 
     once = 3; 
    try 
    { 
     int portNumber1 = Integer.valueOf(args[0]); 
     serverSocket = new ServerSocket(portNumber1); 
    } 
    catch (IOException e) 
    { 
     System.out.println(e); 
    } 

    while (true) 
    { 
     try 
     { 
     clientSocket = serverSocket.accept(); 
     int i = 0; 


     for (i = 0; i < maxClientsCount; i++) 
     { 
      if (threads[i] == null) 
      { 
       String name = ""; 
       (threads[i] = new ClientThreads(clientSocket, threads, name, namesList, listName)).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); 
     } 
    } 
    } 
} 

EDIT: es könnte auch möglich sein, Threads zu ändern [i] auf Threads [i + 1], um den Überblick über verschiedene Clients in bestimmten Teilen zu halten des Codes

Antwort

1

Was müssen Sie statt dessen:

while (!closed) 
{ 
    os.println(inputLine.readLine()); 
} 

ist dies:

String line; 
while ((line = inputLine.readLine()) != null) 
{ 
    os.println(line); 
} 

Dies wird durchstarten, wenn ctrl/d oder ctrl/z gedrückt wird, und main() wird dann beendet. Vorausgesetzt, Sie haben auch Ihre Threads-Daemons erstellt, wird die JVM beendet.

NB dies:

// After Control D/Z is pressed, this code will execute 

nicht wahr ist, und dies:

else if(line.equals(null) || line.equals("null") || line.contains("null")) 

Gefasel ist. line.equals(null) kann per Definition nie wahr sein, sonst wäre NullPointerException anstatt .equals() aufgerufen worden: und warum Sie interessiert sein sollten, ob der Benutzer "null" eingegeben hat, oder etwas, das "null" enthält, ist ein Geheimnis.

Und warum Sie synchronized(listName) in der main() Methode einer Anwendung verwenden, die bis zu diesem Punkt single-threaded ist, ist ein anderes Mysterium.