#c# #binaryreader
#c# #binaryreader
Вопрос:
У меня есть серверное / клиентское приложение.
Оба используют BinaryReader / Writer при обмене данными.
Когда клиент и сервер обмениваются сообщениями быстро, многие за данную секунду, и я выключаю сервер (с помощью встроенной команды, упорядоченное завершение работы) большую часть времени (но не всегда) метод BinaryReader.ReadString() клиента выдает исключение EndOfStreamException, что нормально. Я не понимаю, почему это исключение не изменяет TcpClient.Подключенное свойство к ‘false’?
while(true){
try{
BinaryReader.ReadString()
}
catch(IOException){
if(!TcpClient.Connected)
break;
//BinaryWriter.Write() - this will, eventually, change Connected property to 'false'
}
}
Это будет бесконечно повторяться. Я думал, что свойство Connected изменяется при неудачном сетевом чтении / записи. Если BinaryReader выдает исключения, значит, он не успешно читает, не так ли?
Если я добавлю BinaryWriter.Write() , затем бесконечный цикл прерывается, потому что свойство Connected изменяется на ‘false’.
Связанный вопрос, всегда ли исключение EndOfStreamException указывает на разорванное сетевое соединение или это может означать временную проблему?
Ответ №1:
По замыслу. Из раздела комментариев статьи библиотеки MSDN для TcpClient .Подключено:
Поскольку свойство Connected отражает только состояние соединения на момент последней операции, вы должны попытаться отправить или получить сообщение, чтобы определить текущее состояние. После сбоя отправки сообщения это свойство больше не возвращает true . Обратите внимание, что такое поведение является преднамеренным. Вы не можете надежно проверить состояние соединения, потому что за время между тестированием и отправкой / получением соединение могло быть потеряно. Ваш код должен предполагать, что сокет подключен, и корректно обрабатывать неудачные передачи
Обнаруженный вами обходной путь является правильным.
Комментарии:
1. Я знаю, что меня озадачивает то, что неудачное чтение не изменяет свойство Connected. Я могу не прочитать миллион раз, и Connected по-прежнему «true». Согласно MSDN, неудачное чтение ИЛИ запись изменят свойство Connected, но в моем примере это кажется неверным для чтения, когда они завершаются неудачей.
2. Похоже, что BinaryRead() считывает одни и те же данные снова и снова, не попадая в сокет. Но тогда это будет конфликтовать с BinaryRead() MSDN doc, в котором, похоже, указано, что неудачно прочитанные данные никогда не возвращаются обратно в поток.
3. После дальнейшего тестирования, похоже, это так: сбой BinaryRead вызовет исключение EndOfSocketException и не изменит свойство Connected . Сбой BinaryWrite вызовет исключение IOException->Исключение SocketException и изменит свойство Connected. после чего BinaryRead вызовет исключение IOException->SocketException с сообщением, аналогичным исключению BinaryWrite.