Регистрация Главная Сообщество
Сообщения за день Справка Регистрация
Навигация
Zhyk.org LIVE! Реклама на Zhyk.org Правила Форума Награды и достижения Доска "почета"

Ответ
 
Опции темы
Старый 26.06.2012, 17:29   #1
 Сержант
Аватар для Yukikaze
 
Yukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядомYukikaze в состоянии испепелить взглядом
Регистрация: 01.10.2011
Сообщений: 128
Популярность: 5723
Сказал(а) спасибо: 25
Поблагодарили 174 раз(а) в 105 сообщениях
 
По умолчанию Кастомная бинарная сериализация

Пишу сервер войс чата(может даже по нему статью напишу), ну думаю значит, чего велосипед изобретать, воспользуюсь сериализацией. Описал класс Packet, 3 поля, ничего лишнего. Затем для удобства описал статичный, универсальный класс SerializeHelper с двумя методами которые сериализируют объект в массив байт ну и в обратном направлении.
Каково было мое удивление когда я увидел, что на выходе я получаю массив в 257+ байт, откуда? Посмотрел в отладчике, а там пол массива нулей, я так и присел на месте, что же это за клиент-сервер если он пустыми пакетами в 250+ байт разбрасывается?
Думал не долго, первое, что пришло на ум, это "научить" сериализатор "правильной" сериализации, как говориться с преферансом и куртизанками. Реализовал в своем классе интерфейс ISerializable, класс принял новый вид, описал метод GetObjectData, ничего нового не изобретал.
Код:
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            MemoryStream stream = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(stream);
            writer.Write((byte)this.Command); // т.к. энумератор я наследовал от байта то и привести его к байту тоже не проблема
            writer.Write(this.Sender);
            writer.Write((short)this.Data.Length);
            writer.Write(this.Data);
            info.AddValue("X", stream.ToArray(), typeof(byte[]));
        }
Запись производиться в поток "как есть", без всяких смещений, все данные записываются по очереди, сначала 1 байт команды, затем строка, а так как она заканчивает нуль символом (\0) то и ее длину передавать не нужно, затем идет длинна массива Data, т.к. массивы больше 65536 байт я передавать не собираюсь привел длину к Int16, то есть short, и сэкономил на этом 2 байта , ну а дальше уже идет сам массив. В последней строке метода происходит интересное действие, мы передаем сериализатору первым параметром "имя" передаваемых во втором параметре данных и в третьем параметре говорим, что тип переданных данных это массив байт.
Затем идет конструктор для сериализации, там происходит все по аналогии, только в обратную сторону
Код:
        public Packet(SerializationInfo info, StreamingContext context)
        {
            byte[] byteArray = (byte[])info.GetValue("X", typeof(byte[]));
            MemoryStream stream = new MemoryStream(byteArray);
            BinaryReader reader = new BinaryReader(stream);
            this.Command = (Command)reader.ReadByte();
            this.Sender = reader.ReadString();
            int dataLength = reader.ReadInt16();
            this.Data = reader.ReadBytes(dataLength);
        }
В итоге я все таки попробовал сериализировать полученное творение, передал в параметрах пустую команду(1 байт), пустую строку(еще 1 байт) и массив длинной 0 байт
Код:
Packet p = new Packet(Command.None, string.Empty, new byte[0]);
byte[] data = SerializeHelper.Serialize(p);
на выходе получил 139 байт(это минимальный размер ), что вполне неплохо, т.к. пакет несет в себе всю необходимую для десериализации информацию, такую как имя сборки, версию и т.д.

Пользуйтесь на здоровье, с вами как всегда был Yukikaze
________________
Talk is cheap. Show me the code
— Linus Torvalds

Последний раз редактировалось Yukikaze; 26.06.2012 в 17:43.
  Ответить с цитированием
3 пользователя(ей) сказали cпасибо:
крайслер (26.06.2012), Sinyss (26.06.2012), Skilful (29.04.2013)
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 16:56.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net