Что я могу сделать, когда socket.close () выбрасывает в Java? - PullRequest
13 голосов
/ 10 августа 2011

Начал изучать Java неделю назад, а также решил изучить правильный способ работы с исключениями.Java действительно сводит меня с ума от идеи определения исключений, которые метод может выдавать как часть своей подписи.

В настоящее время я пытаюсь реализовать многопоточный сервер для клиент-серверного приложения.Я был очень удивлен тем, что socket.close() может бросить IOException.Вопрос в том, что мне делать, если это произойдет?

...
final Socket socket = .... // at this point I know that I have a good socket
try {
  ..... // communicating with someone on that side....
} catch(IOException e) {
  // communication failed
  // this fact is useful, I can log it
  // and will just hang up
} finally {
  try {
    socket.close(); // bye-bye
  } catch(IOException e) {
    // anything but logging I can do here?
  }
}
...

Этот фрагмент кода выполняется в отдельном потоке, поэтому я просто должен перехватить все исключения.Проблема в основном психологическая - я знаю, я могу просто оставить блок catch пустым, но я пытаюсь избежать этого трюка.

Есть мысли?

Ответы [ 6 ]

13 голосов
/ 10 августа 2011

Довольно часто вы ничего не делаете, когда закрытие ресурса завершается неудачно.Ведение журнала, вероятно, является хорошей идеей, так что у вас есть шанс выяснить, происходит ли это чаще.

Это отличается, если закрытие ресурса также является «коммитом» или каким-либо другим способом сохраняет изменения:тогда вам нужно будет обрабатывать его так же, как если бы вы обрабатывали исключение в любой другой части: обработайте его.

Обратите внимание, что в Java 7 введено автоматическое управление ресурсами специально для упрощения этих видовстроит.И если вы сейчас изучаете Java, то я бы рекомендовал перейти с самого последнего и самого лучшего.

3 голосов
/ 10 августа 2011

Apache Commons IO (библиотека, без которой я вряд ли смогу написать Java) имеет метод IOUtils.closeQuietly() только для этой цели.

Итак, выможет сделать:

final Socket socket = .... // at this point I know that I have a good socket
try {
  ..... // communicating with someone on that side....
} catch(IOException e) {
  // communication failed
  // this fact is useful, I can log it
  // and will just hang up
} finally {
  IOUtils.closeQuietly(socket);
}

и сохранить себе 5 строк кода.

В качестве бонуса closeQuietly() делает правильные вещи, если сокет нулевой или уже закрыт.И есть перегрузки для всего остального Closeable.

3 голосов
/ 10 августа 2011

Полагаю, это зависит от того, читаете ли вы данные из сокета или записываете в него данные.Если вы прочитали данные и получили всю необходимую информацию, вы можете смело игнорировать исключение.Но если вы записали данные, вы, вероятно, должны предположить, что они не были переданы правильно.

1 голос
/ 10 августа 2011

Нет ничего, что вы можете сделать с исключением, вызванным закрытием, кроме как поймать и зарегистрировать его. Важно то, что если вы позволите ему быть выброшенным, и если будет другое исключение, которое было сгенерировано до того, как будет достигнут метод close, метод close может вызвать исключение, которое замаскирует первое исключение, он не будет отображаться в любом месте, и вы не знаете, в чем была настоящая проблема. Так что вы определенно не хотите этого.

1 голос
/ 10 августа 2011

Это ловит многих людей, это заставляет ловить вложенные исключения, подобные этому.

Вы должны регистрировать это, в идеале, используя что-то надежное, например, Log4J, но в противном случае я бы сказал, что это безопасно игнорировать, другиечем комментарий, говорящий «намеренно игнорируя».

1 голос
/ 10 августа 2011

Как сказано в комментариях, там мало что можно сделать.В любом случае, я предлагаю вам записать ошибку, поэтому, если когда-либо произойдет, у вас, по крайней мере, есть место, чтобы начать поиск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...