Вопрос по java, sockets, outputstream, stream, inputstream – JAVA: Обработка разъединения розетки
InputStream
OutputStream
а такжеSocket
) тогда как я могу сообщить другому концу о разъединении? Есть один способ, которым я знаю - пытаться читать сInputStream
, который бросаетIOException
если соединение закрыто, но есть ли другой способ обнаружить это?Другой вопрос, я посмотрел проблему в интернете и увиделinputStream.available()
не решает эту проблему. Это почему?Дополнительная информация: яЯ прошу другой путь, потому что мой проект становится трудно обрабатывать, если я пытаюсь читать изInputStrem
обнаружить отключение.
Q1 Если вы закроете сокетное соединение на сервере, клиент должен сгенерировать исключение, если не сразу, конечно, при следующей попытке чтения, и наоборот.
Q2 из JavaDocs
Возвращаетоценить числа байтов, которые могут быть прочитаны (или пропущены) из этого входного потока без блокировки при следующем вызове метода для этого входного потока. Следующим вызовом может быть тот же поток или другой поток. Одно чтение или пропуск этого количества байтов не будет блокировать, но может прочитать или пропустить меньшее количество байтов.
Это не указание количества байтов, находящихся в данный момент в потоке, а оценка количества байтов, которые могут быть считаны из выигравшей реализации.блокировать текущий поток
read()
методы бросают это.
user207421
IOException
, Этоможет быть броситьEOFException
в зависимости от того, какой метод чтения он вызвал.
user207421
EOFException
простирается отIOException
это примерно одно и то же, в зависимости от того, какой уровень исключения вы хотите обработать. "может быть" часть это здорово знать
MadProgrammer
пытается прочитать из InputStream, который выбрасывает IOException
Это не правильно. Если узел закрывает сокет:
read()
возвращает -1readLine()
возвращает нольreadXXX()
бросаетEOFException
для любого другого X.
КакInputStream
только имеетread()
методы, он возвращает только -1: он неброситьIOException
в EOS.
Вопреки другим ответам здесь, нет TCP API или метода Socket, который бы сообщал вам, закрыл ли одноранговое соединение. Вы должны попробовать читать или писать.
Вы должны использовать тайм-аут чтения.
InputStream.available()
Безразлично»не решить проблему, потому что это неt вернуть индикацию EOS любого вида. Есть несколько правильных применений, и это нет один из них.
Проблема не "если сервер / клиент закрывает соединение, Проблема в "Что делать, если они не закрывают соединение, а соединение разорвано? "
Нет способа обнаружить это без собственного протокола сердцебиения.
Другой вариант - установить для SO_KEEPALIVE значение true. "
Если для сокета TCP установлена опция keepalive, и в течение 2 часов между сокетами в обоих направлениях не было обмена никакими данными (ПРИМЕЧАНИЕ: фактическое значение зависит от реализации) "
По моему опыту, это гораздо раньше, чем каждые 2 часа. Больше похоже на ~ 5 минут. Кроме использования So_KEEPALIVE, вы по-королевски облажались: P
В моих протоколах связи я использую зарезервированныйстук сердца' байт, который отправляется каждые 2 секунды. Мои собственные filterInputStream и filterOutputStream отправляют / и переваривают байт пульса.
Нет способа O-O-O получить обратный вызов / исключение в момент разрыва соединения. О разорванном соединении вы узнаете только тогда, когда выполняете явное чтение / запись в потоке сокета.
Есть два способа чтения из сокета, а именно. Синхронно читаем побайтово по мере поступления; или подождите до желаемого количества байтов, доступных в потоке, а затем выполните массовое чтение. Вы делаете проверку, вызывая available () в потоке сокета, который дает вам количество байтов, доступных в данный момент для чтения. Во втором случае, если сокетное соединение по какой-то причине разорвано, вы не сможете получить уведомление об этом. В этом случае вам нужно использовать механизм ожидания для вашего ожидания. В первом случае, когда вы делаете явное чтение / запись, вы получаете исключение.
available()
не имеет ничего, чтобы рекомендовать это. Это'Это просто более сложный и более подверженный ошибкам способ блокировки в цикле.
user207421