2011-12-19 4 views
1

Я разрабатываю сетевое приложение, которое отправляет много пакетов. В настоящее время мой метод сериализации - это просто хак, где он принимает список объектов и преобразует их в строку, ограниченную символом канала '|' и сбрасывает его по сетевому потоку (или просто отправляет его через UDP).C# - Сериализация пакетов по сети

Я ищу более чистое решение для этого в C# при минимальном размере пакета (так что огромная сериализация XML).

Мой опыт работы с BinaryFormatter is SLOW. Я также рассматриваю возможность сжатия моих пакетов путем их кодирования в строки base64 и их декодирование на стороне клиента. Я хотел бы получить некоторые сведения о том, как это повлияет на производительность моего приложения.

Кроме того, еще один быстрый вопрос:

Моя установка создает 2 розетки (одна TCP and UDP) и клиент индивидуально соединяется с этими двумя сокетами. Данные сбрасываются либо на основе необходимости (TCP для важных вещей, UDP для неважных вещей). Это мой первый раз, когда я использовал TCP/UDP одновременно и задавался вопросом:

Если есть более унифицированный метод, хотя это и не похоже.

Благодарим за неудобную поддержку.

ответ

2

Я хотел бы использовать бинарный протокол, подобный Google's Protocol Buffers. Используя protobuf-csharp-port от John Skeet, вы можете использовать методы WriteDelimitedTo и MergeDelimitedFrom для IMessage и IBuilder соответственно. Они будут префикс сообщения с количеством байтов, чтобы они могли потреблять на другом конце. Определение сообщений очень легко:

message MyMessage { 
    required int32 number = 1; 
} 

Затем вы строите классы C# с ProtoGen.exe и просто пойти в город. Одно из больших преимуществ для протобуферов (в частности, protobuf-csharp-port) заключается в том, что не каждый конечный пункт необходимо обновлять одновременно. Новые поля могут быть добавлены и использованы предыдущими версиями без ошибок.Эта версия независимость может быть очень мощным, но также может укусить вас, если вы не планируете для него;)

0

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

void SerializeToStream(BinaryWriter serializationStream) 
void BuildFromStream(BinaryReader serializationStream) 

Эта ручная сериализация позволяет создавать небольшие пакеты. Перед отправкой в ​​сокет пакеты имеют префикс длины и префикс с уникальным номером идентификатора пакета. Получающий конец может затем использовать Activator.CreateInstance для создания соответствующего пакета и вызвать BuildFromStream для восстановления пакета.

Пример пакета:

class LocationUpdatePacket : Packet 
{ 
    public int X; 
    public int Y; 
    public int Z; 

    public override void SerializeToStream(BinaryWriter serializationStream) 
    { 
     serializationStream.Write(X); 
     serializationStream.Write(Y); 
     serializationStream.Write(Z); 
    } 
    public override void BuildFromStream(BinaryReader serializationStream) 
    { 
     X = serializationStream.ReadInt32(); 
     Y = serializationStream.ReadInt32(); 
     Z = serializationStream.ReadInt32(); 
    } 
} 
+0

Причина, по которой я избегал BinaryReader/Writer, объясняется тем, насколько медленным был BinaryFormatter. Любые идеи о скорости этого VS BFormatter? –

0

Я занимаюсь разработкой сетевого приложения, которое посылает много пакетов

Заканчивать networkComms.net , библиотека сетевого обмена с открытым исходным кодом, может сэкономить вам немного времени. Он включает protobuf для сериализации, примером которого является here, строка 408.