2013-05-27 18 views
5

Tworzę aplikację klient-serwer, w której użytkownik może włączyć lub wyłączyć serwer z gui; aby to umożliwić, używam klasy zagnieżdżonej SwingWorker. Wszystko wydaje się działać poprawnie, ale kiedy wyłączę serwer i ponownie go uruchomię, to nie działa, prawdopodobnie dlatego, że jest jeszcze otwarta inna instancja, której nie można nadpisać: serwer jest zablokowany na akceptacji () metoda. Chcę zabić poprzednie wystąpienie, gdy użytkownik naciśnie przycisk wyłączania, ale nie wiem jak.Jak zabić instancję klasy w innej klasie?

Oto klasa SwingWorker że daje mi problemy:

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

Everytime włączyć przycisk jest wciśnięty, actionPerformed określa, czy serwer jest już włączony, czy nie, a następnie, jeśli nie działa

SwingWorkGUI swg = new SwingWorkGUI(); 
swg.execute(); 

Bloki wykonywania w poniższej instrukcji, ale tylko w drugim (trzecim, ecc.) Czasie nazywa się:

mainServer = new Server(); 

Server.up to statyczna zmienna, która pomaga mi zabić metodę while (true) na serwerze.

Jak mogę zabić otwarte wystąpienie bez zamykania aplikacji?

+0

Jeśli używasz serwera na osobnym wątku można przechowywać odniesienie do tego wątku i wywołać 'przerwania()' na niego, a następnie oczyścić odniesienie do serwera. To powinno spowodować, że serwer zamknie cokolwiek, co robi. (Prawdopodobnie będziesz również chciał złapać 'InterruptedException's na' Server' i wykonać wewnętrzne czyszczenie w razie potrzeby). – SamYonnou

+0

Wywołanie 'socket.close()' z zewnętrznego wątku w celu przerwania metody 'socket.accept()', a następnie wyłączenie serwera: http://stackoverflow.com/questions/2983835/how-can-i-interrupt- a-serverocket-accept-method – DannyMo

Odpowiedz

0

Jeśli dobrze rozumiem, Twój problem polega na tym, że obiekt ServerSocket jest zablokowany w wywołaniu accept() i trzeba go odblokować. Niektóre opcje:

  1. połączeń ss.close() z innego wątku (zakłada ss to Twój obiekt ServerSocket). Spowoduje to, że accept() rzuci się na SocketException. Numer referencyjny: Javadocs for ServerSocket.close()

  2. Utwórz nowy Socket z innego wątku i połącz się z własnym serwerem. Spowoduje to odblokowanie połączenia accept(). Teraz możesz sprawdzić swoją flagę Server.up.

  3. Ustaw limit czasu na swoim ServerSocket, np. 5 sekund. Spowoduje to, że accept() wyrzuci czas o wartości InterruptedIOException. Numer referencyjny: Javadocs for SO_TIMEOUT