I am going to read messages that are stored consecutively in socket in C++ client that are sent from a C# server. I expect that I can read the size of a message like that:
google::protobuf::uint32 m;
coded_input->ReadVarint32(&m);
cout << m << endl;
Then I want to read the message:
Person person;
CodedInputStream::Limit limit = coded_input->PushLimit(m);
person.ParseFromCodedStream(coded_input);
coded_input->PopLimit(limit);
the C# code looks like:
var person = new Person { Id = 123456, Name = "Fred", Address = new Address { Line1 = "Flat 1", Line2 = "The Meadows ar garą " } };
Stream str = new NetworkStream(socket);
Serializer.SerializeWithLengthPrefix(str, person, PrefixStyle.Fixed32);
It doesn't work.
I get the C++ error (43 is result of cout << m << endl;) (id, name, address are all fields in Person)
43
libprotobuf ERROR google/protobuf/message_lite.cc:123] Can't parse message of type "Person" because it is missing required fields: id, name, address
When I don't read the variant and parse the message straighforward from coded_input
, all is fine (when I change SerializeWithLengthPrefix
to serialize in server's code). However I need a method to distinguish consecutive messages, so I need to know the size of the message I'm going to read. I just don't know how to send the size.
I tried:
Stream buf = new MemoryStream();
Serializer.Serialize(buf, person);
ProtoWriter writer = new ProtoWriter(str, null);
ProtoWriter.WriteInt32((int)buf.Length, writer);
but then I get:
Unhandled Exception: ProtoBuf.ProtoException: Invalid serialization operation with wire-type None at position 0 at ProtoBuf.ProtoWriter.WriteInt32 (Int32 value, ProtoBuf.ProtoWriter writer) [0x00000] in :0
at protobuftest.MainClass.Main (System.String[] args) [0x00097] in /home/lorddidger/studia/csharp/protobuf-test/protobuf-test/Main.cs:31
I am not able to send any int that way. What is wrong?
Update: Actually, my aim is to find a way to transfer an integer (size) with protobuf. I need any example (both C++ and C#) how to handle that because I don't understand all details within protobuf.
I noticed that SerializeWithLengthPrefix send prefix (4 uint32) that look like: size 0 0 0. The size is number of bytes of the message after serialization (I guess). I thought PrefixStyle.Fixed32 says there is only one uint32 before the message but there are 4!
Finally, I thought you should use ProtoWriter.WriteInt32((int)buf.Length, writer) to transfer integers because I followed suggestion from somwhere in the internet which I suppose is a workaround relevant to C++. Now I see you shouldn't write varints - they are related to the engine and that is to sophisticated to spend time on.
Should I send a message with an int? How should I distinguish that from next message that size is stored in the first one?
I see C# can hadle prefixes fine but is there ANY COMPATIBLE with C++ and C# way to state size of a message? Otherwise, there is no **ing way to queue messages what I would find irrational.