Преобразование объекта в массив байтов в C#, отправка его через сокет, а затем преобразование обратно в объект

Итак, у меня есть сервер и клиент, которые передают различные данные туда и обратно. Первоначально у меня был сложный метод, который проходил через массив байтов и преобразовывал все его переменные и строки одну за другой в то, чем они должны были быть. Я узнал, что могу поместить все переменные в объект и преобразовать его в массив байтов, используя

private static byte[] ObjectToByteArray2(Object obj)
    {
        if (obj == null)
            return null;
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream();
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }

И преобразовать его обратно с помощью

private static Object ByteArrayToObject(byte[] arrBytes)
    {
        MemoryStream memStream = new MemoryStream();
        BinaryFormatter binForm = new BinaryFormatter();
        memStream.Write(arrBytes, 0, arrBytes.Length);
        memStream.Seek(0, SeekOrigin.Begin);
        Object obj = (Object)binForm.Deserialize(memStream);
        return obj;
    }

Проблема в том, что как только я отправляю этот массив байтов по сети в другое приложение, я не могу просто использовать этот метод для его обратного преобразования, я получаю сообщение об ошибке «Невозможно найти сборку 'test1s, версия = 1.0.0.0, культура = нейтральный, PublicKeyToken=null». test1s — это просто название маленькой серверной программы, которую я сделал, чтобы играть с этим. Очевидно, что приложению нужна дополнительная информация, чтобы преобразовать этот массив обратно в объект, так что я могу это сделать, или я неправильно решаю проблему?

Здесь я хочу получить объект, состоящий только из нескольких переменных и строк, преобразовать его в массив байтов, отправить в другое приложение и преобразовать обратно в объект. Таким образом, мне не нужно играть с массивом байтов, чтобы извлечь все мои переменные и строки.

Спасибо


person cost    schedule 14.11.2010    source источник
comment
На вашем месте я бы использовал отладчик, чтобы попытаться понять это. Если, конечно, вы не верите, что отладчик — мать всего зла. Если вы не понимаете, что я имею в виду, загрузите это: stackoverflow.com/questions/602138/   -  person YWE    schedule 14.11.2010


Ответы (4)


arrow_upward
8
arrow_downward

Здесь поможет множество готовых библиотек сериализации. У BinaryFormatter есть некоторые (IMO) нежелательные функции, в частности, он будет работать только с одной и той же (ну, в значительной степени) dll на обоих концах.

XmlSerializer, DataContractSerializer и JavaScriptSerializer являются хорошими реализациями на основе текста и будут нормально работать с совместимым контрактом на обоих концах (одинаковые свойства и т. д. — не обязательно одного и того же типа/версии).

Если у вас есть умеренные потребности в пропускной способности или вам нужна более высокая производительность процессора, я бы порекомендовал protobuf-net (предупреждение: я написал это), который является быстрым двоичным сериализатором, который может помочь.

person Marc Gravell    schedule 14.11.2010

arrow_upward
4
arrow_downward

Это будет работать, если обе стороны канала связи имеют ссылку на точно одну и ту же сборку и точно ту же версию этой сборки, на которую каким-то образом ссылается программа или которая находится в ПКК.

Если вам нужен механизм, более устойчивый к несоответствию версий, рассмотрите возможность использования вместо него XMLSerializer (но учтите, что добавление/удаление/изменение полей/свойств может привести к некорректному поведению, если версии не совпадают).

Если требуется компактный формат, вы можете просмотреть буферы протокола Google.

person cdhowie    schedule 14.11.2010

arrow_upward
1
arrow_downward

Если вы хотите отправить список строк (или словарь строк), это не проблема, просто отправьте список (или словарь) строк. Ваша проблема связана с тем, что вы пытаетесь отправить тип данных, который другой проект не распознает. Вам даже не нужно менять какую-либо из ваших функций, вам просто нужно изменить то, что вы отправляете. В качестве альтернативы вы можете ссылаться на test1 из программы, получающей данные.

person Alxandr    schedule 14.11.2010

arrow_upward
0
arrow_downward

Напишите свой собственный конвертер объектов из/в байты вместо использования BinaryStream.

Если вы настаиваете, переместите этот объект в его собственную сборку и добавьте его к обеим сторонам в качестве ссылки. Таким образом, .NET Framework должна иметь возможность десериализовать объект.

person Lex Li    schedule 14.11.2010