C++ Proto3: Parsing messages from the TCP stream

Skip to first unread message

Vimla Sharma

Jan 14, 2023, 3:11:17 AM1/14/23
to Protocol Buffers

I am getting Proto3 messages from a server on the tcp, and the server team provided the proto3 file which I compiled and included in my project.  So I parse the message in the following way successfully: Example message type 1:
MessageType1  m1;
        bool ok =  m1.ParseFromArray(tcp_buffer, tcp_len);
My question is: how would  I parse a message from 5 possibly available, MessageType1-5? Is there any factory or reflection based parsing?

Please note my tcp buffer for a given message is complete, i.e. I have the full message encoded in the tcp_buffer from the server.

Any help will be appreciated. 


Michael Ngarimu

Jan 15, 2023, 4:15:08 AM1/15/23
to Protocol Buffers
Without seeing the actual proto one has to make some assumptions. 

Assuming MessageType1-5 are all intended to be "top-level" messages, here are some possibilities I can think of; others may more/better ideas.
  1. Attempt to deserialize each type
    1. I think this might still succeed if the data on the wire contains fields that match all of the field IDs (and types?) of any message you're attempting to deserialize. 
  2. Ask if the protocol can be changed to have a single top-level message. This top-level message might use either oneof, or any.
    1. oneof allows testing for the type to deserialize but requires that the proto be changed when new messages types are added.
    2. any does not require that proto change when new messages types are added. However, it does require attempting to deserialize the different message types your receiver cares about. 
      1. Could be considered safer than sampling attempting to deserialize each message type because any data  on the wire contains "type". However, your client must still be compiled with the metadata for that type.  
  3. Ask if the protocol can be change to send the serialized proto allowing fully dynamic messages on the wire where the on the wire data contains all metadata necessary to deserialize the message. 

Vimla Sharma

Jan 16, 2023, 7:33:36 PM1/16/23
to Protocol Buffers
Thank you, it worked. I used "any".

 google::protobuf::Any any;
    rc = any.ParseFromArray(ptr, len);
    if (!rc) {
        return false;
    std::string data;
    if (any.Is<Struct>()) {

Reply all
Reply to author
0 new messages