2012-07-24 15 views
12

Estoy usando protobuf para serializar el mensaje que envío a través de una conexión de socket en C++. Para la comunicación, me gustaría agregar un encabezado a los mensajes que indican la duración del mensaje. ¿Qué piensas de esta implementación? Investigué un poco y eso es lo que armé.Prefijo de longitud para mensajes protobuf en C++

¿Hay alguna forma más agradable de hacerlo? ¿Puede esta implementación causar algún problema? Sé que hay soporte API para Java, pero desafortunadamente no para 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

ver esto [respuesta] (http://stackoverflow.com/questions/2340730/are-therec-c-equivalents-for-the-protocol-buffers-delimited-io-functions-in-ja) – alavrik

+0

es necesario que el búfer sea del tipo int8 sin signo? – Chani

+0

¿Cómo acepta socket-> write() el buffer del tipo google :: protobuf :: uint8? – Chani

Respuesta

5

Es más común el uso de varint (por ejemplo WriteVarint32) en lugar de fixed32 (donde tiene WriteLittleEndian32), pero la práctica de la delimitación de las corrientes protobuf mediante un prefijo de longitud es el sonido.

Cuestiones relacionadas