2012-07-24 6 views
12

Ich benutze Protobuf zum Serialisieren von Nachrichten, die ich über eine Socket-Verbindung in C++ senden. Für die Kommunikation möchte ich den Nachrichten einen Header hinzufügen, der die Länge der Nachricht angibt. Was denkst du über diese Implementierung? Ich habe etwas recherchiert und das habe ich zusammengestellt.Länge Präfix für Protobuf Nachrichten in C++

Gibt es einen schöneren Weg, dies zu tun? Kann diese Implementierung Probleme verursachen? Ich weiß, dass es API-Unterstützung für Java gibt, aber leider nicht für C++.

bool send_message(int socket, my_protobuf::Message message) 
{ 
    google::protobuf::uint32 message_length = message.ByteSize(); 
    int prefix_length = sizeof(message_length); 
    int buffer_length = prefix_length + message_length; 
    google::protobuf::uint8 buffer[buffer_length]; 

    google::protobuf::io::ArrayOutputStream array_output(buffer, buffer_length); 
    google::protobuf::io::CodedOutputStream coded_output(&array_output); 

    coded_output.WriteLittleEndian32(message_length); 
    message.SerializeToCodedStream(&coded_output); 

    int sent_bytes = write(socket, buffer, buffer_length); 
    if (sent_bytes != buffer_length) { 
    return false; 
    } 

    return true; 
} 

bool recv_message(int socket, my_protobuf::Message *message) 
{ 
    google::protobuf::uint32 message_length; 
    int prefix_length = sizeof(message_length); 
    google::protobuf::uint8 prefix[prefix_length]; 

    if (prefix_length != read(socket, prefix, prefix_length)) { 
    return false; 
    } 
    google::protobuf::io::CodedInputStream::ReadLittleEndian32FromArray(prefix, 
     &message_length); 

    google::protobuf::uint8 buffer[message_length]; 
    if (message_length != read(socket, buffer, message_length)) { 
    return false; 
    } 
    google::protobuf::io::ArrayInputStream array_input(buffer, message_length); 
    google::protobuf::io::CodedInputStream coded_input(&array_input); 

    if (!message->ParseFromCodedStream(&coded_input)) { 
    return false; 
    } 

    return true; 
} 
+1

siehe diese [Antwort] (http://stackoverflow.com/questions/2340730/are-there-c-äquivalents-for-the-protocol-buffers-delimited-io-functions-in-ja) – alavrik

+0

ist es notwendig, dass der Puffer vom Typ int8 intangiert ist? – Chani

+0

Wie akzeptiert Ihr socket-> write() den Puffer des Typs google :: protobuf :: uint8? – Chani

Antwort

5

Es ist häufiger VarInt zu verwenden (z WriteVarint32) statt fixed32 (wo man WriteLittleEndian32 haben), aber die Praxis protobuf Ströme begrenzen, indem sie mit Länge prefixing ist Klang.