Вы получили хорошие ответы. Просто поймайте исключение и обработайте его локально. Если вам нужно передать это другому коду, но не можете, поскольку метод run()
не допускает никаких исключений проверки, вы можете обернуть исключение в какое-либо исключение RuntimeException. Если метод запуска выполняется непосредственно в потоке (поскольку, вероятно, это Runnable), вам следует позаботиться о повторном создании завернутого исключения.
Что касается результата от readLine()
, он вернет null
, когда больше нечего читать. В случае сокета это когда другая сторона полностью закрывает сокет (любое внезапное завершение или нечистое закрытие обычно приводит к исключению в вашем коде, поскольку ОС будет отправлять уведомление о закрытии сокета другого типа).
У меня есть одно предостережение, поскольку вы заключаете сокет в java.io.BufferedReader
. Вы должны быть очень осторожны при использовании этого в любом производственном коде.
Опасность заключается в том, что BufferedReader плохо справляется с исключениями во время чтения. Это особенно проблема, если вы включили тайм-аут для сокета, поэтому код будет автоматически получать периодические исключения из операционной системы. Тайм-аут (или другое исключение) может произойти во время заполнения буфера внутри считывателя. Если вы попытаетесь повторно использовать объект после исключения, он проигнорирует все предыдущее содержимое в буфере. Пакет(ы), которые были получены ранее, теряются без уведомления, и нет никакого способа получить эти байты.
Обратите внимание, что существуют другие виды исключений сокетов, которые не означают, что сокет был потерян. Например, посмотрите на определение java.io.InterruptedIOException
. У этого есть общедоступная переменная, которая сообщает о количестве байтов, успешно переданных в самом последнем запросе ввода-вывода (чтение или запись). Это означает, что операция ввода-вывода может быть выполнена снова, чтобы получить или отправить оставшиеся байты для пакета.
Если при каком-либо исключении ваш дизайн заключается в немедленном закрытии считывателя и сокета, метод будет работать правильно.
Правильный способ чтения из сокета — использовать поток сокета напрямую, использовать NIO (ByteBuffers и тому подобное) или использовать хорошо написанную сетевую библиотеку с хорошими абстракциями над этими классами более низкого уровня (доступно несколько с открытым исходным кодом).
person
Kevin Brock
schedule
23.03.2010