序列化Protobuf对象并使用ØMQ/ ZMQ发送

时间:2015-03-10 21:22:36

标签: c# c++ zeromq protobuf-net

我有一个protobuf对象,我从一个C#应用程序(使用clrZmq)发送到本地机器上的C ++服务(使用zmq C ++绑定)(用于测试)。我尝试使用以下

从C#发送我的对象
Taurus.Odds odds = Util.GetFakeOdds();
using (var context = ZmqContext.Create())
using (var socket = context.CreateSocket(SocketType.REQ))
{
    byte[] buffer = null;
    socket.Connect(TARGET); // TARGET = "tcp://127.0.0.1:6500"

    Taurus.FeedMux mux = new Taurus.FeedMux();
    mux.type = Taurus.FeedMux.Type.ODDS;
    mux.odds = odds;

    SendStatus status = socket.Send(mux.ToByteArray());
    if (status == SendStatus.Sent)
    {
        int i;
        byte[] arr = socket.Receive(buffer, SocketFlags.None, out i);
        Taurus.Bet bet = buffer.ToObject<Taurus.Bet>();
    }
...
}

我通过扩展方法将Taurus.Odds对象序列化到byte[]的位置

public static byte[] ToByteArray(this object o)
{
     if(o == null)
          return null;
     BinaryFormatter bf = new BinaryFormatter();
     using (MemoryStream ms = new MemoryStream())
     {
         bf.Serialize(ms, o);
         return ms.ToArray();
     }
}

我在C ++应用程序中看到代码收到消息,但C ++ ZMQ类无法正确反序列化。我有一些Java代码以相同的方式发送到C ++代码而没有问题。我的问题是,我是否正确地通过ZMQ在上面发送我的对象,如果不是我做错了什么?

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

这是您的错误:

  

我通过扩展方法

Taurus.Odds对象序列化为byte[]
...
BinaryFormatter bf = new BinaryFormatter();
...

您似乎不知道BinaryFormatter是什么。 与ProtoBuf 无关。 docs说出以下内容:

  

序列化和反序列化对象或连接对象的整个图表,以二进制格式

二进制格式是特定于.NET的实现细节。由于版本控制支持不佳,它的非常严格。它主要用于.NET远程处理日,今天使用它通常被认为是一个坏主意,因为有更好的序列化器。

正如您所看到的,您的C ++应用程序无法读取它,因为它不是protobuf格式。

所以抛弃这个方法并用一些适当的protobuf序列化代码替换它,如in the protobuf-net docs所述。您需要在对象中添加[ProtoContract][ProtoMember]属性。然后你可以这样写:

public static byte[] ToByteArray<T>(this T o)
{
     if (o == null)
          return null;

     using (MemoryStream ms = new MemoryStream())
     {
         ProtoBuf.Serializer.Serialize(ms, o);
         return ms.ToArray();
     }
}