2013-02-21 10 views
6

Tak, napisałem wątek po stronie klienta, który próbuje readObject() ze strumienia gniazda.Java - readObject() i setSoTimeout()

Ten wątek działa tak długo, jak długo klient jest podłączony.

Połączenie z serwerem można zamknąć w interfejsie GUI klienta. Jeśli klient zdecyduje się rozłączyć (nie spowoduje to wyjścia z programu klienta), klikając opcję menu "odłącz" , gniazdo zostanie zamknięte, a isConnected ustawiona na wartość false.

Ponieważ klient odczytuje wątek, próbuje uzyskać readObject() ze strumienia, podczas gdy połączenie może zostać zamknięte przez GUI, ustawiam limit czasu na 250ms (setSoTimeout(250)).

@Override 
public void run() 
{ 
    this.connection = this.connectionHandler.getSocket(); 
    while(connectionHandler.isConnected()) 
    { 
    this.readCircle(); 
    } 
    this.connectionHandler.setReadTaskRunning(false); 
} 

private void readCircle() 
{ 
    try 
    { 
    this.connection.setSoTimeout(250); 
    this.connectionHandler.readData(); //this uses readObject(). 
    } 
catch(SocketTimeoutException timeout){} 
catch(...){} 

}

wiem, że readObject() będzie blokować, oraz w celu sprawdzenia, czy klient jest wciąż podłączony, i wraped go w while, który sprawdza (co timeout) jeśli gniazdo klient nadal jest podłączony.

Moje pytanie teraz:

W przypadku, gdy rozpoczyna readObject() aby uzyskać obiekt przeszedł przez serwer, próbuje ją przeczytać, ale podczas przetwarzania wystąpi przekroczenie limitu czasu, będą dane o strumieniu być „uszkodzony” w pewien sposób, ponieważ został anulowany. A może po prostu niech blok readObject() i wychwycić wyjątek, jeśli wątek GUI chce zamknąć gniazdo.

Nie mam dużego doświadczenia z podstawkami i może moje podejście jest w ogóle złe.

+1

isConnected() nie zwraca wartości false, jeśli węzeł sieciowy został rozłączony. Musisz złapać i obsłużyć EOFException. – EJP

+0

Tak, masz rację. Na 'catch (...) {}' muszę złapać kilka wyjątków. 'EOFException' catch wywoła' forceDisconnect() ', aby zamknąć zasoby po stronie klienta, a także dostosować Elementy GUI dla użytkownika. – Hexa

Odpowiedz

2

Limit czasu odczytu gniazda spowoduje, że SocketTimeoutException zostanie zrzucony przez readObject(). Możesz nie móc ponownie użyć tego ObjectInputStream, a strumień może zostać uszkodzony, ponieważ jego aktualna pozycja pozostanie w dużej mierze niezdefiniowana.

Prawdopodobnie można to naprawić tylko przez zamknięcie i ponowne otwarcie połączenia.