2013-05-27 17 views
5

Ich mache eine Client-Server-Anwendung, in der der Benutzer den Server von einem GUI ein- oder ausschalten kann; Damit es funktioniert, verwende ich eine SwingWorker-Klasse. Alles scheint richtig zu funktionieren, aber wenn ich den Server ausschalte und wieder einschalte, funktioniert es nicht, wahrscheinlich, weil noch eine andere Instanz davon offen ist, die nicht überschrieben werden kann: Server ist auf der Annahme blockiert () Methode. Ich möchte die vorherige Instanz beenden, wenn der Benutzer die Abschalttaste drückt, aber ich weiß nicht wie.Wie kann ich eine Instanz einer Klasse in einer anderen Klasse beenden?

Hier ist die Swingworker Klasse, die mir Probleme gibt:

class SwingWorkGUI extends SwingWorker 
    { 
     @Override 
     protected Integer doInBackground() throws Exception { 
      int delay = 1000; 
      final Timer time = new Timer(delay, null); 
      time.addActionListener(new java.awt.event.ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (Server.up == true){ 
         upTimeMillis += 1000; 
         long diff = upTimeMillis/1000; 
         long numHrs = diff/60; 
         diff = diff%60; 
         long numMins = diff/60; 
         long numSecs = diff%60; 
         upTime.setText(numHrs + ":" + numMins + ":" + numSecs); 
        } 
        else { 
         upTime.setText("Server Actually Down"); 
         time.stop(); 
        } 
       }   
      }); 
      time.start(); 
      mainServer = new Server(); 
      return null; 
     } 
    } 

Jedesmal, die Turn On-Taste gedrückt wird, bestimmt die actionPerformed, ob der Server bereits eingeschaltet ist oder nicht, dann nicht, wenn

SwingWorkGUI swg = new SwingWorkGUI(); 
swg.execute(); 
läuft

Die Ausführung blockiert in der folgenden Anweisung, aber nur die zweite (dritte, ecc.) Zeit es heißt:

Server.up ist eine statische Variable, die mir hilft, die while (true) -Methode im Server zu beenden.

Wie kann ich die offene Instanz beenden, ohne alle Anwendungen zu schließen?

+0

Wenn Sie den Server auf einem separaten Thread ausführen Sie einen Verweis auf diesen Thread speichern und rufen 'Interrupt()' drauf und dann den Verweis auf den Server aufzuräumen. Dies sollte dazu führen, dass der Server das beendet, was er gerade tut. (Sie werden wahrscheinlich auch 'InterruptedException' auf dem' Server' abfangen und bei Bedarf eine interne Bereinigung vornehmen). – SamYonnou

+0

Rufen Sie 'socket.close()' von einem externen Thread auf, um die 'socket.accept()' Methode zu unterbrechen und dann den Server herunterzufahren: http://stackoverflow.com/questions/2983835/how-can-i-interrupt- Eine Server-Socket-Accept-Methode – DannyMo

Antwort

0

Wenn ich Ihr Problem richtig verstanden habe, ist das ServerSocket Objekt auf dem accept() Anruf blockiert und Sie müssen es entsperren. Einige Optionen:

  1. Anruf ss.close() von einem anderen Thread (übernimmt ss ist Ihr ServerSocket Objekt). Dadurch wird accept() eine SocketException werfen. Referenz: Javadocs for ServerSocket.close()

  2. Erstellen Sie einen neuen Socket von einem anderen Thread und stellen Sie eine Verbindung zu Ihrem eigenen Server her. Dies entsperrt den accept() Anruf. Jetzt können Sie Ihre Server.up Flagge überprüfen.

  3. Setzen Sie eine Zeitüberschreitung für Ihre ServerSocket, z. 5 Sekunden. Dadurch wird accept() einen InterruptedIOException bei Timeout werfen. Referenz: Javadocs for SO_TIMEOUT

Verwandte Themen