使用由google的protobuf序列化的protobuf-net反序列化数据的问题

Chu*_*huu 5 c# c++ serialization cross-platform protobuf-net

我目前正在处理在一个应用程序(C++)中序列化的代码,并需要在另一个应用程序(C#)中反序列化它.我正在尝试使用谷歌proto + protobuf-net,但有些事情失败了.

.cc和.cs消息定义文件都是使用它们各自的编译器从同一个.proto文件生成的.

数据通过UDP发送,消息(~40B)很容易适合单个数据报.

在C++大小上,boost :: asio用于传输数据,相关代码为:

ProtocolBufferdata data;
...
boost::asio::streambuf b;
std::ostream os(&b);
data.SerializeToOstream(&os);
m_Socket.send_to(b.data(), m_Endpoint);
Run Code Online (Sandbox Code Playgroud)

我很确定这是正常的,因为使用wireshark我至少可以看到我期望在数据报中的所有字符串.在C#端,使用Begin/End接收,我们在回调中有以下内容:

byte[] buffer ....        

public void ReceiveData(IAsyncResult iar)
{
    try
    {
        Socket remote = (Socket)iar.AsyncState;
        int recv = remote.EndReceive(iar);
        using (MemoryStream memStream = new MemoryStream())
        {
            memStream.Write(buffer, 0, recv);
            ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData >(memStream);
            onReceive(data);
        }
    }
    catch (Exception ex)
    {
        ...
    }
    finally
    {
        socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveData), socket);
    }
}
Run Code Online (Sandbox Code Playgroud)

缓冲区确实具有预期的字节数,并具有告警字符串.protobuf-net容器具有所有默认值.

我对这里发生的事情感到有些困惑,并且几乎不可能将调试器附加到客户端应用程序,因为它被部署为另一个与远程调试器不兼容的应用程序的插件.我很感激任何建议,这让我很难过.

Mar*_*ell 9

回滚你的流 - 它在最后,所以Read将不返回任何数据:

memStream.Write(buffer, 0, recv);
memStream.Position = 0; // <===========here
ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData>(memStream);
Run Code Online (Sandbox Code Playgroud)

或者,使用重载的构造函数来准备流:

using (MemoryStream memStream = new MemoryStream(buffer, 0, recv))
{
    ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData>(memStream);
Run Code Online (Sandbox Code Playgroud)