Задать вопрос
@Vadim_Student

Как гарантировано закрыть сокет через ServerSocket?

Есть случаи, в которых сокет через ServerSocket не может быть гарантированно закрыт (Выброс IOExceptionдля .close() по причинам:

1. уже закрытый сокет;
2. Прерывание потока при закрытии;
3. Проблемы с сетевым стеком ОС
4. Неправильное состояние сокета.

И получается такая ситуация, что все случаи, кроме 1 не могут быть корректно обработаны? Что же такого понаписать в catch (IOException){...}для try {socket.close()}, чтобы гарантировать закрытие здесь и сейчас. В голову приходит повторный socket.close(), но уже какие-то рекурсивные извращения как по мне (также ничего не гарантирует?). Также, в спецификации написано про закрытие сокета (ServerSocket) через PrintWrite.close() или BufferedReader.close(), если мы их инициализировали потоками ServerSocket, но они также выбрасывают IOException. Как же быть?
  • Вопрос задан
  • 165 просмотров
Подписаться 2 Сложный 4 комментария
Помогут разобраться в теме Все курсы
  • Нетология
    Java-разработчик с нуля
    12 месяцев
    Далее
  • Академия Эдюсон
    Java-разработчик + ИИ
    8 месяцев
    Далее
  • ProductStar × РБК
    Профессия: Java-разработчик + ИИ
    9 месяцев
    Далее
Решения вопроса 1
Vamp
@Vamp
Что же такого понаписать в catch (IOException){...}для try {socket.close()}, чтобы гарантировать закрытие здесь и сейчас.

Ничего. Как вы и сказали, 1 пункт можно обработать. 2 пункт тоже можно. Можно перехватить InterruptedIOException, сбросить interrupted флаг потока, повторно попробовать закрыть сокет и в конце восстановить interrupted флаг. Но при правильно спроектированном приложении такая ситуация невозможна. Так что я бы не стал добавлять проверку на такой случай. Если вдруг она возникнет, значит нужно пересмотреть архитектуру приложения, а не обвешиваться дополнительными проверками. Это, кстати, так же относится и к 1 случаю. Если сокет закрывается дважды, значит код кривой и его надо переделать.

В остальных случаях из java вы ничего не сможете сделать, так как должно что-то очень серьёзно сломаться, чтобы close начал стрелять исключениями. Максимум, что вы можете сделать - отпустить ссылку на ваш экземпляр ServerSocket, чтобы GC при сборке мог попробовать с этим что-то сделать.

Также, в спецификации написано про закрытие сокета (ServerSocket) через PrintWrite.close() или BufferedReader.close(), если мы их инициализировали потоками ServerSocket, но они также выбрасывают IOException. Как же быть?

Эти два класса - просто обёртки, которые тупо вызывают close у потока, который они оборачивают. Так что поведение их метода close в точности соответствует поведению обёрнутого ими стрима.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы