Поврежден BufferedStream при повторном подключении отброшенного NetworkStream

Вот сценарий...

сервер

  • я имею TcpListener сервер, который принимает соединения
  • Когда соединение установлено, я заверну TcpClient.GetStream() в буферизованном потоке.
  • Тогда я использую BinaryFormatter десериализовать входящие данные из потока

клиент

  • Я подключаюсь к серверу
  • При подключении я обернуть TcpClient.GetStream() в буферизованном потоке.
  • Тогда я использую BinaryFormatter сериализовать данные через поток.

Все работает скважины до тех пор, пока соединение остается активным. Я проверял в течение нескольких часов.

Эта проблема

  • Затем я останавливаю сервер для имитации сбоя сети (я использую localhost)
  • Клиент обнаружит ошибку (исключение брошено / обработано)
  • Клиент будет повторно подключиться позже с новым TcpClient и новый BufferedStream
  • Клиент будет использовать новый BinaryFormatter снова начать сериализацию данных.

Однако теперь сервер получит все виды странных исключений десериализации. Я опустился до уровня байтов потока и, к моему удивлению, обнаружил, что поток поврежден!... но только после повторного подключения scenerio. И, избавляясь от BufferedStream и используя NetworkStream напрямую исправляет проблему. Вы можете повторно подключиться много раз, не видя этой проблемы.

Что происходит с BufferedStream? Каждое переподключение я создаю новый BufferedStream, но может ли предыдущий поток повлиять на новый как-нибудь?

Кто-нибудь видел что-нибудь подобное?

К сожалению, я не могу опубликовать весь код, но вот пример того, что я делаю...

Пример кода сервера

while (true)
{//Accept connections and spawn threads to handle incoming connections
     TcpClient connection = server.AcceptTcpClient();
}

//Done on another thread
Stream stream = new BufferedStream(connection.GetStream());
BinaryFormatter formatter = new BinaryFormatter();
object data = formatter.Deserialize(stream);

Пример кода клиента

_connection = new TcpClient();
_connection.Connect(_remoteAddress);
NetworkStream netStream = _connection.GetStream();
Stream stream = new BufferedStream(netStream);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, data);
stream.Flush();

Без использования BufferedStream все работает нормально. Также при повторном подключении вышеуказанный клиентский процесс повторяется.

1 ответ

Решение

Я решил проблему повторного подключения, не жертвуя большой скоростью, сначала записав в MemoryStream, а затем вызвав MemoryStream.WriteTo(Stream), чтобы записать данные в небуферизованный NetworkStream. Это решение работает, но по-прежнему не объясняет проблему BufferedStream и является менее идеальным для отправки больших объектов, поскольку весь объект должен быть сериализован перед отправкой чего-либо.

Все еще не уверен, что проблема BufferedStream. И, чтобы сделать его более запутанным, я обнаружил, что код работает безупречно на одной машине, но не на другой. Возможно, это проблема с драйверами?

Но, сериализация в MemoryStream сначала, а затем вызов MemoryStream.WriteTo(Stream) работает достаточно хорошо для меня и прекрасно работает на всех протестированных машинах, поэтому я пошел с этим.

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