Java — readObject() и setSoTimeout()

Итак, я написал поток на своей стороне клиента, который пытается readObject() из потока сокета.

Этот поток работает, пока клиент подключен.

Соединение с сервером может быть закрыто в графическом интерфейсе клиента. Если клиент решит отключиться (это не приведет к выходу из клиентской программы), щелкнув пункт меню «отключить», сокет будет закрыт, а для isConnected будет установлено значение false.

Поскольку поток чтения клиентов пытается readObject() из потока, в то время как соединение может быть закрыто через графический интерфейс, я установил тайм-аут на 250 мс (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(...){}

}

Я знаю, что readObject() будет блокироваться, и чтобы проверить, подключен ли клиент, я обернул его в while, который проверяет (каждый тайм-аут), подключен ли клиентский сокет.

Мой вопрос сейчас:

В случае, если readObject() начинает получать объект, переданный сервером, пытается его прочитать, но при обработке происходит тайм-аут, не будут ли данные в потоке каким-то образом "повреждены", потому что он отменен. Или я должен просто позволить блоку readObject() и поймать исключение, если поток GUI хочет закрыть сокет.

Я не очень разбираюсь в сокетах и, возможно, мой подход вообще неверен.


person Jonas Bräuer    schedule 21.02.2013    source источник
comment
isConnected() не возвращает false, если одноранговый узел отключился. Вы должны поймать и обработать EOFException.   -  person user207421    schedule 21.02.2013
comment
Да, вы правы. В catch(...){} мне нужно поймать кучу исключений. EOFException catch вызовет forceDisconnect(), чтобы закрыть ресурсы на стороне клиента, а также настроить элементы графического интерфейса для пользователя.   -  person Jonas Bräuer    schedule 21.02.2013


Ответы (1)


Тайм-аут чтения сокета приведет к тому, что readObject() выдаст SocketTimeoutException. Возможно, вы не сможете повторно использовать этот ObjectInputStream, и поток может быть поврежден, поскольку его текущая позиция останется в значительной степени неопределенной.

Вероятно, это можно исправить, только закрыв и снова открыв соединение.

person Audrius Meskauskas    schedule 21.02.2013