2012-12-18 5 views
8

Ich versuche, eine Protokollbuffer-Nachricht über TCP zu senden, aber auf der Empfängerseite bekomme ich eine Fehlermeldung "Fehlende Pflichtfelder" beim Versuch analysieren, obwohl anscheinend alle Felder da sind. Ich sende einen 4-Byte-Header vor der Nachricht, die die Länge der Nachricht enthält. HierGoogle Protokoll Puffer - Fehlende Pflichtfelder, obwohl alle Felder scheinbar vorhanden sind

ist die Botschaft Definition:

message ReplayRequest { 
    required string channel = 1; 
    required uint32 start = 2; 
    required uint32 end = 3; 
} 

Auf der Clientseite Ich bin kodiert den Header und die Serialisierung der Nachricht in einen Vektor.

ReplayRequest req; 
req.set_channel("channel") 
req.set_start(1); 
req.set_end(5); 
int byte_size = req.ByteSize(); 
std::vector<uint8_t> write_buffer(HEADER_SIZE + byte_size); 
encode_header(...); 
req.SerializeToArray(&write_buffer[HEADER_SIZE], byte_size); 

Dies ist ein hex-Druck der resultierenden Puffer, in dem die ersten 4 Bytes der codierte Nachrichtenlänge (13 Bytes).

00 00 00 0d 0a 07 63 68 61 6e 6e 65 6c 10 01 18 05 

Auf der Serverseite, erhalte ich den Header, es dekodieren und dann N Bytes empfangen, wobei N die Größe der Nachricht in der Kopfzeile angegeben ist. Der Puffer in dem Server mit dem Header entfernt ist:

0a 07 63 68 61 6e 6e 65 6c 10 01 18 05 

etwas genau das ist das gleiche wie die codierten Client-Seite minus dem Header, aber wenn ich versuche, diesen Puffer ich einen Fehler ParseFromArray:

libprotobuf ERROR c:\umdf_runtime\protobuf-2.4.1\src\google\protobuf\message_lit 
e.cc:123] Can't parse message of type "ReplayRequest" because it is missing 
required fields: channel, start, end 

beim Debuggen bemerkte ich, dass der Punkt, an dem Dekodieren auf diesem Teil der protobuf Code generierte versagt ist:

bool ReplayRequest::IsInitialized() const { 
    if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; 

    return true; 
} 

has_bits_ als Null auf der Server-Seite wird gelesen aus irgendeinem Grund, aber ich kann nicht herausfinden warum.

Irgendwelche Ideen?

Ich verwende boost :: asio für den Netzwerkteil, wenn es darauf ankommt.

aktualisieren

Da bat ich den Code bin Entsendung, die parseFromArray nennt.

request_.ParseFromArray(&data_buffer_, data_buffer_.size()); 

request_ ist ein ReplayRequest Membervariable, bis zu diesem Anruf nichts getan wird.

data_buffer_ ist ein Vektor <uint8_t> wo die TCP-Daten empfangen werden.

Ich habe bestätigt, dass es bei 13 Bytes korrekt bemessen ist und das ist seine hex-Speicherauszugsdatei, die dieselbe ist, die ich erhalte, wenn ich die Pufferclientseite nach der Serialisierung ablege.

0a 07 63 68 61 6e 6e 65 6c 10 01 18 05 

Update 2

Ich kann den Puffer in einer anderen Instanz von ReplayRequest auf der Clientseite, d.h .:

...snip... 
req.SerializeToArray(&write_buffer[HEADER_SIZE], byte_size); 
ReplayRequest test; 
test.ParseFromArray(&write_buffer[HEADER_SIZE], byte_size); 

Test erfolgreich bevölkert mit den richtigen Feldern analysieren.

+0

Wenn der Server sagt, dass es nicht über * jede * der erforderlichen Felder aus, dann, wenn ich frage mich, Sie zu extrahieren und Parsing Die Nachricht ist falsch auf dem Server. Könnten Sie bitte den Code posten, der ParseFromArray aufruft? –

+0

Ich bemerke, dass Ihre 4-Byte-kodierte Nachrichtengröße Header Big-Endian zu sein scheint ... Dekodieren Sie es richtig als Big-Endian auf der Empfängerseite? Ich denke, Sie müssen es richtig dekodieren, weil Sie das richtige N bekommen. –

+0

@James Der Header wird korrekt dekodiert, Sie können sehen, dass der Server-Puffer, den ich gedruckt habe, genau 13 Bytes ist, wie codiert. – indiosmo

Antwort

5

Das Problem ist, dass Sie einen Zeiger auf den Vektor und nicht einen Zeiger auf die Vektoren Daten übergeben.

statt
request_.ParseFromArray(&data_buffer_, data_buffer_.size());

versuchen
request_.ParseFromArray(&data_buffer_[0], data_buffer_.size());

+0

Das ist es. Ich habe zuvor einen einzelnen Puffer auf dem Server erhalten, also & data_buffer_ [HEADER_SIZE] hat gut funktioniert. Nachdem ich die Puffer aufgeteilt habe, habe ich den Accessor entfernt. Vielen Dank. – indiosmo

+0

np, froh zu helfen :) – g19fanatic

Verwandte Themen