Преобразовать объект в байтовый массив в C #, отправить его через сокет, а затем преобразовать обратно в объект - PullRequest
6 голосов
/ 14 ноября 2010

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

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, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null '."test1s - это просто название маленькой серверной программы, которую я создал, чтобы поиграть с этим.Очевидно, что приложению требуется некоторая дополнительная информация для преобразования этого массива обратно в объект, поэтому есть ли способ, которым я могу это сделать, или я решаю проблему неправильно?

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

Спасибо

Ответы [ 4 ]

8 голосов
/ 14 ноября 2010

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

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

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

4 голосов
/ 14 ноября 2010

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

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

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

1 голос
/ 14 ноября 2010

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

0 голосов
/ 14 ноября 2010

Записать свой собственный объект из / в байтовый конвертор вместо того, чтобы использовать BinaryStream, должно работать.

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

...