В чем разница между подключением и временем ожидания чтения для сокетов?

182

3 вопроса:

  1. В чем разница между подключением и временем ожидания чтения для сокетов?

  2. Что означает время ожидания подключения, равное «бесконечности»? В какой ситуации он может оставаться в бесконечном цикле? и что может вызвать то, что бесконечный цикл умирает?

  3. Что означает тайм-аут чтения, установленный на «бесконечность»? В какой ситуации он может оставаться в бесконечном цикле? и что может вызвать то, что бесконечный цикл умирает?

corgrath
источник

Ответы:

228

1) В чем разница между подключением и временем ожидания чтения для сокетов?

Тайм-аут соединения - это время ожидания при установлении первоначального соединения; т.е. завершение установления соединения TCP. Тайм-аут чтения - это время ожидания чтения данных 1 . В частности, если серверу не удается отправить байт <timeout> секунд после последнего байта, возникнет ошибка тайм-аута чтения.

2) Что означает время ожидания соединения, установленное на "бесконечность"? В какой ситуации он может оставаться в бесконечном цикле? и что может вызвать то, что бесконечный цикл умирает?

Это означает, что попытка подключения может потенциально заблокировать навсегда. Не существует бесконечного цикла, но попытка подключения может быть разблокирована другим потоком, закрывающим сокет. ( Thread.interrupt()Звонок также может помочь ... не уверен.)

3) Что означает тайм-аут чтения, установленный на «бесконечность»? В какой ситуации он может оставаться в бесконечном цикле? Что может привести к тому, что бесконечный цикл закончится?

Это означает, что вызов readв потоке сокета может блокироваться навсегда. Еще раз, бесконечного цикла нет, но он readможет быть разблокирован Thread.interrupt()вызовом, закрытием сокета и (конечно) другим концом, отправляющим данные или закрывающим соединение.


1 - Это не ... как думал один комментатор ... тайм-аут о том, как долго сокет может быть открыт или бездействовать.

Стивен С
источник
8

Это значения времени ожидания, установленные JVM для установления соединения TCP и ожидания при чтении данных из сокета.

Если значение установлено в бесконечность, вы не будете ждать вечно. Это просто означает, что у JVM нет тайм-аута, и ОС будет отвечать за все тайм-ауты. Однако тайм-ауты в ОС могут быть очень длинными. В какой-то медленной сети я видел таймауты до 6 минут.

Даже если вы установите значение времени ожидания для сокета, оно может не сработать, если время ожидания происходит в собственном коде. Мы можем воспроизвести проблему в Linux, подключившись к узлу, заблокированному брандмауэром, или отключив кабель от коммутатора.

Единственный безопасный подход для обработки тайм-аута TCP - это запуск кода соединения в другом потоке и прерывание потока, когда это занимает слишком много времени.

ZZ Coder
источник
«Если значение установлено в бесконечность, вы не будете ждать вечно». Пока речь не идет о дискуссии о значении «бесконечности», может случиться так, что вы будете ждать очень и очень долго. У нас был случай здесь, где HttpURLConnection.getResponseCode()висел ок. неделю, пока мы не перезапустили процесс. Очевидно, что на стороне JVM не было установлено время ожидания, а также на стороне ОС Linux.
Том Финк
Последний абзац не правильный. Время соединения истекает максимум через минуту. Отдельная тема совершенно не нужна. Вы можете, конечно, иметь чтения, которые выполняются вечно, если нет данных. Однако Javadoc ошибочен из-за того, что время ожидания соединения по умолчанию бесконечно. Это не так.
маркиз Лорн
1
@comeGetSome Это не правильно. Вы можете отключить сокет для ввода. Это приведет к тому, что заблокированное чтение встретится с концом потока.
маркиз Лорн
@comeGetSome: мне пришлось реализовать это с помощью потока, который содержит ссылку на открытое соединение HTTP URL. Когда указанный поток закрывает соединение, другой поток выдает «java.net.SocketException: Socket closed». Спасибо, ошибка JDK-8075484 за то, что заставил меня сделать это!
fmcato
@comeGetSome Конечно, вы можете позвонить, Socket.shutdownInput()не держась за руки? NB. Эти тайм-ауты применяются TCP, а не JVM.
Маркиз Лорн