2014-01-19 2 views
3

Я создаю программу, которая должна эффективно отправлять данные между клиентом и сервером. Чтобы четко организовать пакеты, я использую сериализацию. Однако, когда я сериализую эти пакеты, данные излишне большие. Я объясню, что я делаю, чтобы вы могли понять, что мне нужно.C# - Более эффективная сериализация для пакетов

Мои классы пакетов работают следующим образом. У меня есть объект Packet:

using System; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 

[Serializable] 
public class Packet 
{ 
    public static byte[] Serialize(Object o) 
    { 
     MemoryStream ms = new MemoryStream(); 
     BinaryFormatter bf = new BinaryFormatter(); 
     bf.Serialize(ms, o); 
     return ms.ToArray(); 
    } 

    public static Object Deserialize(byte[] bt) 
    { 
     MemoryStream ms = new MemoryStream(); 
     BinaryFormatter bf = new BinaryFormatter(); 

     ms.Write(bt, 0, bt.Length); 
     ms.Position = 0; 

     object obj = bf.Deserialize(ms); 

     ms.Close(); 

     return obj; 
    } 
} 

Затем я могу создать другие классы, которые наследуют от класса пакетов, вот пример:

using System; 

[Serializable] 
public class PacketUserInfo : Packet 
{ 
    public string Name; 
    public int Age; 
} 

Тогда это очень просто, чтобы поместить это в массив байтов и отправьте его (конечно, вышеуказанный пакет является просто примером). Однако размер результирующего массива по меньшей мере в 10 раз больше, чем если бы я использовал BinaryWriter и вручную записывал информацию.

Почему сериализованные данные такие большие? Есть ли способ уменьшить его, сохраняя при этом все, что организовано с пакетами, как свои собственные классы?

Примечание: Я намереваюсь сериализовать простые свойства, подобные этому, ничего необычного.

+0

Хотя я не могу дать вам точные причины такого поведения, я хотел бы рекомендовать библиотеку сериализации, которую я соавтор, Migrant - https://github.com/antmicro/Migrant. Это позволяет сериализовать ваши классы с небольшими накладными расходами в результирующих данных и практически без кода шаблона. Фактически для простых случаев он не требует никакого кода. Кроме того, он предоставляет такие функции, как сложные графики объектов с циклами и т. Д. –

+0

Я посмотрю на это ... Если это не займет много времени, чтобы переключиться на него, я попробую. Благодарю. – Jordan

+0

'BinaryFormatter' не является хорошим выбором для машинного обжига машины, если две машины имеют разные DLL-версии основных .NET-DLL (скажем, что одна машина не запускала обновления для Windows, когда вышло исправление для .NET) данные не будут desearalize. (Я даже не рекомендую его сохранять на диск для одного и того же компьютера, единственное место, которое нужно использовать, не беспокоясь о проблемах с десарализацией, - это связь IPC на одном компьютере) –

ответ

3

Где вы говорите «Почему Сериализованный данные [...] больше, чем это было бы, если бы я должен был использовать BinaryWriter и вручную записывать информацию» с информации вы имеете в виду свойства значения. Сериализатор, который вы используете, сериализует не только данные , но и некоторую информацию о классе . Вы можете увидеть это, просмотрев сериализованные данные в текстовом редакторе.

Есть ли способ уменьшить его, сохраняя при этом все, что организовано с пакетами, как их собственные классы?

Используйте более специализированные сериализации, как protobuf или библиотеки suggested by @Piotr.

Также я думаю, что ваш код сериализации не должен находиться в базовом классе Packet, а в отдельном классе, например PacketEncoder.

Смежные вопросы