UDP Paket序列化和删除开销

时间:2011-08-22 09:22:51

标签: c# serialization udp

我是关于用信息序列化一个paket,它作为传入udp paket的答案。传入的UDP paket非常紧凑,包含我想要查看的信息。

当我发送回复时,数据包差不多大200倍(1036字节对57字节..)并且包含很多空格,类实例的名称和它的结构(如可以为空等等)。 / p>

这个问题可能听起来很广泛,但这里的问题是什么?我知道我的解决方案是序列化整个对象,包括它的类名,命名空间等。收件人不需要,也不会,也不能拿这个信息。他们需要直接进入数据结构。

2 个答案:

答案 0 :(得分:1)

您应该尝试Protobuf。它支持属性序列化模型(事实上,它支持几个属性模型,包括DataContract WCF模型),并且明显快于内置.Net二进制序列化(比甚至DataContract序列化更快) 。 Protobuf也设计得尽可能紧凑 - 因此您应该减少数据包大小的问题。

编辑:您还可以使用界面实现自己的序列化范例。例如:

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>();
    }
}

答案 1 :(得分:0)

这里的问题是,你的对手期望一个类似xml的扁平结构,它可能看起来像XML,但根据xml规范无效/良好。

您可以调整.net序列化程序(DataContract或XMLSerializer),只要您记住输出的内容可能不再有效或格式良好。检查以下两个链接,它们应指向正确的方向。

编辑:使用XMLSerializer添加了BinaryFormatting,不确定您的输出格式,但也许这是一个帮助。

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; }

}