Подтвердить что ты не робот

Что-нибудь, что я могу сделать, когда socket.close() выбрасывает Java?

Начал обучение 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 пустым, но я стараюсь избегать этого трюка.

Любые мысли?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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() делает правильную вещь, если сокет равен null или уже закрыт. И есть перегрузки для чего-нибудь еще Closeable.

Ответ 4

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

Ответ 5

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

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

Ответ 6

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