2017-10-03 2 views
-1

de Capture de l'exécution du programme (en haut à gauche: le serveur, le reste sont des clients): enter image description hereComment fermer une fenêtre à l'aide de commande D/Z sans quitter le programme entier (prise Java multithread)

Dans le coin inférieur droit fenêtre, je suis en train d'appuyer sur le contrôle D (Mac) (pour les fenêtres, il est le contrôle Z) pour sortir la fenêtre en bas à droite/client seul sans quitter l'application entière/programme, mais il ne semble pas fonctionner parce que je peut toujours taper "ça n'a pas marché" et il sort le message.

Ma question est: Quelles sont les modifications que je peux apporter au code suivant afin que lorsqu'un client appuie sur Control D, il fermera juste une fenêtre/client et ne quittera pas l'application entière?

Une partie du code qui devrait fermer la fenêtre (vide):

  //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); 
       } 
      } 
      } 

REMARQUE: PASSER LE RESTE et faites défiler vers le bas si vous connaissez déjà la réponse

complet Code de ClientThreads.java :

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) 
    { 
    } 
    } 


} 

code complet de 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); 
    } 
    } 
} 

code complet de 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: il pourrait être également possible de modifier les discussions [i] [i à fils + 1] afin de garder une trace des différents clients dans certaines régions du code

Répondre

1

Qu'est-ce que vous avez besoin au lieu de ceci:

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

est ceci:

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

Cela fall-through lorsque ctrl/d ou ctrl/z est pressée, le cas échéant, et main() sera alors sortie. Pourvu que vous ayez également créé vos démons de threads, la machine virtuelle Java se fermera.

NB ceci:

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

est pas vrai, et ceci:

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

est radotage. line.equals(null) ne peut jamais être vrai, par définition, sinon un NullPointerException aurait été jeté au lieu d'appeler .equals(): et pourquoi vous devriez être intéressé par si l'utilisateur a tapé « null », ou quelque chose contenant « null », est un mystère.

Et pourquoi vous utilisez synchronized(listName) dans la méthode main() d'une application qui est à ce point monothread est un autre mystère.