Из того, что я знаю, блокирующий прием на сокете TCP не всегда обнаруживает ошибку соединения (из-за сбоя в сети или сбоя удаленной конечной точки), возвращая значение -1
или вызывая исключение ввода-вывода: иногда он может просто висеть бесконечно.
Одним из способов решения этой проблемы является установка времени ожидания для получения блокировки. В случае, если известна верхняя граница для времени приема, эта граница может быть установлена как время ожидания, и соединение может считаться потерянным просто по истечении времени ожидания; когда такая верхняя граница не известна априори, например, в системе pub-sub, где соединение остается открытым для приема публикаций, время ожидания, которое нужно установить, будет несколько произвольным, но его истечение может вызвать запрос пинг / понга, чтобы проверить, что соединение (и конечная точка тоже) все еще установлено.
Интересно, может ли использование асинхронного приема решить проблему обнаружения сбоя соединения? В boost :: asio я бы назвал socket::asynch_read_some()
, регистрируя обработчик для асинхронного вызова, в то время как в java.nio я бы настроил канал как неблокирующий и зарегистрировал его в селекторе с флагом интереса OP_READ
. Я предполагаю, что правильное обнаружение сбоя соединения означало бы, что в первом случае обработчик будет вызываться с кодом ошибки, отличным от 0, в то время как во втором случае селектор выберет неисправный канал, но последующий read()
на канале либо вернет -1
, либо бросит IOException
.
Гарантируется ли это поведение при асинхронном приеме или могут быть сценарии, в которых после сбоя соединения, например, в boost :: asio, никогда не будет вызываться обработчик или в java.nio селектор никогда не будет выбирать канал?
Большое спасибо.