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