开发者

UDP Paket Serialization and removal of overhead

I'm about serialize a paket with information, which act as an answer on a开发者_如何学Python incoming udp paket. The incoming UDP paket is very compact and contains exactly the information I want to see.

When I send my reply, the packet is nearly 200 times bigger (1036 byte against 57 byte..) and contains a lot of white spaces, name of the class instance and it's structure (like nullable and so on).

The question may sounds wide but what are the problem here? I understand that my solution is serialize the whole object, including it's class name, namespace and so on. The recipient don't need, won't and Can't take this info. They need to go directly into the data structure.


You should probably try out Protobuf. It supports the attributed serialization model (in fact, it supports several attributed models, including the DataContract WCF model), and is significantly faster than built-in .Net binary serialization (faster than even DataContract serialization). Protobuf is also designed to be as compact as possible - so you should have fewer problems with packet size.

Edit: You could also implement your own serialization paradigm, by using an interface. For example:

public interface IBinarySerializable
{
    void Serialize(BinaryWriter writer);
    void Deserialize(BinaryReader reader);
}

public static class BinaryReaderWriterExtensions
{
    public static void Write(this BinaryWriter writer, IBinarySerializable value)
    {
        value.Serialize(writer);
    }

    public static T Read<T>(this BinaryReader reader)
        where T : IBinarySerializable, new()
    {
        var val = new T();
        val.Deserialize(reader);
        return val;
    }

    public static void ReadInto(this BinaryReader reader, IBinarySerializable value)
    {
        value.Deserialize(reader);
    }

    public static void WriteList<T>(this BinaryWriter writer, IList<T> list, Action<BinaryWriter, T> singleValueWriter)
    {
        writer.Write(list.Count);
        foreach (var item in list)
            singleValueWriter(writer, item);
    }

    public static IEnumerable<T> ReadList<T>(this BinaryReader reader, Func<BinaryReader, T> singleValueReader)
    {
        var ct = reader.ReadInt32();
        for (var i = 0; i < ct; i++)
            yield return singleValueReader(reader);
    }
}

public class WantsToBeSerialized : IBinarySerializable
{
    public int ID;
    public string CustomerName;
    public List<string> Nicknames;
    public SomeOtherSerializableObject Thing;

    void IBinarySerializable.Serialize(BinaryWriter writer)
    {
        writer.Write(ID);
        writer.Write(CustomerName);
        writer.WriteList(Nicknames, (w, value) => w.Write(value));
        writer.Write(Thing);
    }

    void IBinarySerializable.Deserialize(BinaryReader reader)
    {
        ID = reader.ReadInt32();
        CustomerName = reader.ReadString();
        Nicknames = new List<string>(reader.ReadList(x => x.ReadString()));
        Thing = reader.Read<SomeOtherSerializableObject>();
    }
}


The problem here is, that your counterpart is expecting a flat, xml-like structure, which may look like XML, but is not valid/wellformed according the xml specifications.

You can tweak the .net serializers (DataContract or XMLSerializer), as long as you have in mind that what you´re outputting might no longer be a valid or wellformed. Check the following two links, they should point you in the right direction.

  • Omitting Namespaces and
  • MSDN EmittingDefaultValue

EDIT: Added BinaryFormatting using XMLSerializer, not sure about your output format but maybe this is a help.

class Program
{
    static void Main(string[] args)
    {
        TestObject data = new TestObject() { Name = "Claus", Firstname = "Santa"};

        MemoryStream stream = new MemoryStream();

        XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
        xsn.Add(String.Empty, String.Empty);

        XmlSerializer serializer = new XmlSerializer(typeof(TestObject));

        XmlDictionaryWriter binaryDictionaryWriter = XmlDictionaryWriter.CreateBinaryWriter(stream);

        serializer.Serialize(binaryDictionaryWriter, data,xsn);

        binaryDictionaryWriter.Flush();

        stream.Seek(0, SeekOrigin.Begin);

        StreamReader reader = new StreamReader(stream);

        string s = reader.ReadToEnd();
    }
}

[Serializable()]
public class TestObject
{
    [XmlAttribute]
    public string Name { get; set; }

    [XmlIgnore]
    public string Firstname { get; set; }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜