Я на самом деле немного смущен примером кода - вопрос предполагает , что эти вопросы открыты достаточно долго, но код более типичен для очень коротких пакетов; для длительного соединения я бы ожидал увидеть здесь один из API-интерфейсов асинхронной синхронизации, а не API-интерфейс синхронизации.
Розетки, которые умирают без следа, очень распространены, особенно когда они распределены между несколькими промежуточными устройствами, которые все должны были бы обнаружить отключение. В частности, беспроводные сети иногда пытаются искусственно поддерживать работу сокетов, поскольку довольно часто кратковременно теряется беспроводное соединение, поскольку устройства не хотят, чтобы это каждый раз прерывало соединение.
Таким образом, довольно распространено использование какого-то пульса на соединениях, чтобы вы могли отслеживать, кто все еще действительно жив.
В качестве примера - у меня здесь есть сервер веб-сокетов, который в теории обрабатывает как изящные отключения (через определенную последовательность, указывающую на закрытие), так и неуместное закрытие сокета (неожиданно разрывая соединение) - но 19k соединений, которые я видел за последний час или около того, 70 умерло, не поразив ни одного из них. Поэтому вместо этого я отслеживаю действия против (медленного) сердцебиения и убиваю их, если они не отвечают слишком долго.
Re timeout; вы можете попробовать ReceiveTimeout
, но это поможет вам, только если вы не ожидаете больших пробелов в трафике.