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

标签 c# c++ zeromq protobuf-net

我有一个 protobuf 对象,我从 C# 应用程序(使用 clrZmq)发送到本地机器上的 C++ 服务(使用 zmq C++ 绑定(bind))(用于测试)。我尝试使用以下方法从 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 正确地发送了我的对象,如果没有,我做错了什么?

感谢您的宝贵时间。

最佳答案

这是你的错误:

I am serializing to my Taurus.Odds object to byte[] via the extension method

...
BinaryFormatter bf = new BinaryFormatter();
...

你似乎没有意识到什么BinaryFormatter是。它与 ProtoBuf 没有任何关系docs说以下内容:

Serializes and deserializes an object, or an entire graph of connected objects, in binary format.

二进制格式 是特定于 .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();
     }
}

关于c# - 序列化 Protobuf 对象并使用 ØMQ/ZMQ 发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28974327/

相关文章:

c# - ZeroMq recv 不阻塞

python - 如何使用 pyzmq 发送带有 PUB/SUB 模式的字典?

zeromq - Majordomo 经纪人 : handling large number of connections

c# - 使命名元组的名称出现在序列化的 JSON 响应中

c# - 查找数组中的列总数

c++ - C++中异常对象的范围

c++ - 令人晕眩的游戏关卡表示(格式)

c# - MVC 4 - 更改密码错误 : "Index (zero based) must be greater than or equal to zero..."

c# - 单击复选框时的 ASP.NET MVC 提交表单

c# - 如何通过泛型使用嵌套类列表创建基类列表而不进行强制转换