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