Исключение BinaryFormatter
Я пытаюсь переместить граф объектов из серверного процесса в клиент. И это работает. По крайней мере, это работает, когда и клиент, и сервер находятся на моей виртуальной машине dev. Это также работает, когда я запускаю сервер на моей базовой машине (клиент на dev vm).
Он перестает работать, когда я запускаю сервер на моем медиацентре ПК. Исключение составляет:
Двоичный поток '0' не содержит допустимого BinaryHeader. Возможные причины: неверное изменение потока или версии объекта между сериализацией и десериализацией.
Все три компьютера являются 64-разрядными компьютерами Windows 7. Я использую TCPClient и TCPListener вместе с BinaryFormatter
класс, чтобы сделать тяжелую работу.
Передаваемые данные читаются из файла с использованием стандартного FileStream
объект.
Если на стороне клиента я сериализирую буферы в файл, содержимое (согласно BeyondCompare) на самом деле, кажется, отличается?!?
Все строковые свойства в моих объектах кодируются Base64 в установщиках и декодируются в получателях.
Я могу опубликовать код, но я не уверен, где находится проблемная область? Есть идеи?
1 ответ
Обновление: я, кажется, решил эту проблему. У меня была точка останова, где клиент прочитал ответ сервера
tcpClient.GetStream().Read(buffer, 0, buffer.Length);
и отметил, что с "проблемного" сервера было прочитано меньше байтов. После быстрого Google я нашел эту статью http://social.msdn.microsoft.com/Forums/en-US/ncl/thread/759f3f2f-347b-4bd8-aa05-fb7f681c3426 в которой Дейв Мюррей предлагает:
Есть несколько способов справиться с этим более элегантно. Если вы не планируете повторно использовать соединение для чего-то еще, самое простое - это то, что предлагает nobugz. Когда сервер завершит отправку данных, у него будет Close(), это конец соединения. Когда клиент прочитает все данные, отправленные до закрытия, чтение начнет возвращать 0, и в этот момент вы знаете, что сервер не планирует отправлять что-либо еще.
Итак, я обновил свой код с одного чтения до:
var buffer = new byte[32768];
var totalBytesRead = 0;
var bytesRead = tcpClient.GetStream().Read(buffer, 0, buffer.Length);
do
{
totalBytesRead += bytesRead;
bytesRead = tcpClient.GetStream().Read(buffer, totalBytesRead, bytesRead);
} while (bytesRead > 0);
и обновил код моего сервера, чтобы закрыть соединение согласно посту. И согласно комментарию от @leppie, я, вероятно, могу удалить свои свойства в оболочке Base64...