2016-04-05 9 views
0

Ich programmiere eine Chat-App mit Sockets in Java. Ich habe diese Methode, die so oft aufgerufen wird, wie Clients mit dem Server verbunden sind.Sockets - Trennen eines Clients beim Trennen der Serververbindung


public class ClientInfo implements Serializable 
{ 
    public ObjectOutputStream writer; 
    public ObjectInputStream reader; 
    public String user_name; 

    public ClientInfo(ObjectOutputStream writer, ObjectInputStream reader, String name) 
    { 
     this.reader = reader; 
     this.writer = writer; 
     this.user_name = name; 
    } 
}//end class 

/*Client side code*/ 
    void remove_online_user(ClientInfo client_to_remove) 
     { 
      try 
      { 
       client_to_remove.reader.close(); //this should trigger server handler in client 
       client_to_remove.writer.close(); 
      } 
      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
     }//end remove_online_users() 


Auf der Clientseite, erstelle ich ein ClientInfo Objekt wie diese


client = new ClientInfo(
        new ObjectOutputStream(client_socket.getOutputStream()), 
        new ObjectInputStream(client_socket.getInputStream()), 
        user_name); 

new ServerHandler(client, this); 

Und schließlich die ServerHandler

class ServerHandler implements Runnable 
{ 
    private ClientInfo server; 
    private ClientBackEnd client_back_end; 


    public ServerHandler(ClientInfo server, ClientBackEnd client_back_end) 
    { 
     this.server = server; 
     this.client_back_end = client_back_end; 
    }//end constructor 


    /*method invoked by start() call in constructor, manages communication between client and server*/ 
    public void run() 
    { 
     try 
     { 
      MessageInfo message; 
      while ((message = (MessageInfo) server.reader.readObject()) != null) 
      { 
       if (message.clients != null) 
       { 
        for (ClientInfo cd : message.clients) 
        { 
         if (client_back_end.listModel.contains(cd)) continue; 
         client_back_end.listModel.addElement(cd); 
        } 

        for (Object cd : client_back_end.listModel.toArray()) 
        { 
         if (message.clients.contains(cd)) continue; 
         client_back_end.listModel.removeElement(cd); 
        } 

       } 
       else 
       { 
        System.out.println("\n" + message.message_contents); 
       } 
      } 
     } 
     catch (ClassNotFoundException | IOException e) 
     { 
      //This should trigger during the execution of remove_online_user(); 
      client_back_end.disconnect_from_server(); 
     } 
    }//end run() 

Mein Ziel ::

Wenn das (sorry für den gesamten Code einfügen, ich mein Bestes versuche, es so weit wie möglich zu kondensieren) Benutzer stoppt den Server, alle Clients müssen getrennt werden. Während des Vorgangs remove_online_user() sollte das Schließen des ObjectInputStream/ObjectOutputStream eine Ausnahme im Client-Server-Handler auslösen. Aber momentan tut es das nicht. Was mache ich falsch?

(ich im Voraus entschuldigen, wenn ich nicht genügend Informationen bereitstellen habe, ich will nicht, dass jemand mit 4 ganze .java-Dateien verblüffen Sie mich bitte, wenn weitere Informationen benötigt wird.)

Antwort

0

den Socket schließen, wird triggern Sie einen EOFException in der Peer readObject() Methode.

Aus demselben Grund ist Ihre Leseschleife ungültig. readObject() gibt am Ende des Streams keine Null zurück.

+0

Hm, ich weiß, dass EOFException eine Unterklasse von IOException ist und dass diese Ausnahme ausgelöst wird. Ich verstehe nicht, was Sie meinen, wenn Sie sagen, dass readObject() nicht am Ende des Streams null zurückgibt? Kannst du bitte Erklären? – user3487243

+0

Es scheint eine vollkommen klare Aussage zu mir. Welchen Teil davon verstehst du nicht? – EJP

+0

"am Ende des Streams" ist was ich nicht verstehe. Aus welchem ​​Grund gibt es nicht Null zurück? Wie beantwortet das meine Frage? – user3487243