Физическое отключение от сети и временная ошибка сокета 10057

У моего клиента есть приложение для Windows, в котором между двумя компьютерами установлено сетевое соединение. Система должна справиться с потерей соединения. Это достигается путем сохранения счетчика на позиции клиента, который сбрасывается при каждом получении данных с сервера. Если счетчик достигает 60 секунд (т.е. мы не слышали от сервера в течение 60 секунд), он выполняет ожидаемое действие, чтобы справиться с потерей соединения.

Однако у клиента есть проблема, когда иногда соединение теряется, но клиент не выполняет ожидаемое действие. После расследования выясняется, что это временная проблема, вызванная тем, что клиентский сокет к серверу иногда вызывает ошибку 10057 (WSAENOTCONN / "Сокет не подключен"), когда соединение теряется. Поскольку клиент ведет себя по-разному, когда он получает ошибку сокета, клиент не получает желаемого поведения, когда он получает эту ошибку сокета. Это не трудно исправить, но я немного озадачен другим поведением.

Чтобы воспроизвести проблему, я физически вытаскиваю сетевой кабель из задней части моего сервера. В большинстве случаев на стороне клиента мы просто не получаем никаких данных через сокет и не получаем ошибку. Однако возникает некоторая доля времени, когда возникает ошибка 10057. Может ли кто-нибудь пролить свет на то, почему существует такое несоответствие? Клиентский сокет является неблокирующим сокетом STREAM.

2 ответа

Решение

Я ожидаю, что вы получите сообщение об ошибке, только если попытаетесь что-то отправить. Именно тогда TCP-соединение обнаружит, что оно не может достичь другой конечной точки. Это займет различное количество времени для обнаружения сбоя, в зависимости от времени прохождения сигнала в сети. Может существовать опция "keep alive", которая заставляет сокет периодически отправлять что-либо для обнаружения сбоя, даже когда приложение находится в режиме ожидания.

WSAENOTCONN это ошибка в вашем приложении. Это не результат потерянного соединения. Результат потерянного соединения WSAECONNRESET. Ваш код должен быть WSAECONNRESET, и затем продолжите использовать соединение, как будто оно все еще было в силе. Тогда вы получите WSAENOTCONN.

Другие вопросы по тегам