Поврежден 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) работает достаточно хорошо для меня и прекрасно работает на всех протестированных машинах, поэтому я пошел с этим.