I am currently working on code that serializes in one app (C++) and needs to deserialize it in another (C#). I am trying to use google proto + protobuf-net but something is failing.
Both the .cc and the .cs message definition files were generated with their respective compilers, from the same .proto file.
The data is being sent via UDP, and the messages (~40B) easily fit into a single datagram.
On the C++ size, boost::asio is being used to transmit the data, the relevant code being:
ProtocolBufferdata data;
...
boost::asio::streambuf b;
std::ostream os(&b);
data.SerializeToOstream(&os);
m_Socket.send_to(b.data(), m_Endpoint);
I am fairly sure this is working correctly, since using wireshark I can at least see all the strings I expect in the datagram. On the C# side, using Begin/End recieve, we have the following in the callback:
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);
}
}
The buffer does have the expected number of bytes in it, and has the tell-tale strings. The protobuf-net container has all default values.
I am a bit puzzled about what is going on here, and it is almost impossible to attach a debugger to the client application since it is deployed as a plug-in to another application that does not play well with a remote debugger. I would appreciate any advice, this has me stumped.
Rewind your stream - it is at the end, so Read
will return no data:
memStream.Write(buffer, 0, recv);
memStream.Position = 0; // <===========here
ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData>(memStream);
alternatively, use the overloaded constructor to prepare the stream:
using (MemoryStream memStream = new MemoryStream(buffer, 0, recv))
{
ProtoData data = ProtoBuf.Serializer.Deserialize<ProtoData>(memStream);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With