TCP를 통해 프로토콜 버퍼 메시지를 보내려고하지만 수신 측에서 '누락 필수 입력란'오류가 발생합니다. 분명히 모든 필드가 존재하더라도 구문 분석합니다. 메시지의 길이를 포함하는 메시지 앞에 4 바이트 헤더를 보냅니다.Google 프로토콜 버퍼 - 모든 입력란이 분명히 표시되어 있어도 필수 입력란이 누락되었습니다.
message ReplayRequest {
required string channel = 1;
required uint32 start = 2;
required uint32 end = 3;
}
클라이언트 측 내가 헤더를 인코딩 및 벡터에 메시지를 직렬화하고있어에서 : 여기
는 메시지 정의입니다.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);
이것은 결과 버퍼의 16 진수이며, 처음 4 바이트는 인코딩 된 메시지 길이 (13 바이트)입니다. 서버 측
00 00 00 0d 0a 07 63 68 61 6e 6e 65 6c 10 01 18 05
는 I 헤더를 수신하여 디코딩하고 N 헤더에보고 메시지 크기 N 바이트를 수신한다. 정확히 하나의 인코딩 된 클라이언트 측 마이너스 헤더와 동일한
0a 07 63 68 61 6e 6e 65 6c 10 01 18 05
,하지만이 버퍼를 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
을
I 디코딩 실패 점이 protobuf이 부분에서 생성 한 코드에 눈치 디버깅하는 동안 :
bool ReplayRequest::IsInitialized() const {
if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;
return true;
}
has_bits_가 서버 측에서 0으로 판독되고 웬일인지. 그러나 나는 이유를 해석 할 수 없다.
아이디어가 있으십니까?
중요한 경우 네트워크 부분에 boost :: asio를 사용하고 있습니다.
내가 parseFromArray를 호출하는 코드를 게시하도록하겠습니다 요청으로 업데이트
.
request_.ParseFromArray(&data_buffer_, data_buffer_.size());
request_는이 호출이 끝날 때까지 ReplayRequest 멤버 변수입니다.
data_buffer_는 TCP 데이터가 수신되는 <uint8_t>입니다.
올바르게 크기가 13 바이트로 확인되었으며이 16 진수 덤프는 직렬화 후에 버퍼 클라이언트 측을 덤프 할 때와 같은 결과입니다. 나는 클라이언트 측에서 ReplayRequest의 또 다른 인스턴스로 버퍼를 구문 분석 할 수 있어요 2
0a 07 63 68 61 6e 6e 65 6c 10 01 18 05
업데이트, 즉 :
...snip...
req.SerializeToArray(&write_buffer[HEADER_SIZE], byte_size);
ReplayRequest test;
test.ParseFromArray(&write_buffer[HEADER_SIZE], byte_size);
테스트가 성공적으로 올바른 필드로 채워집니다.
시도 서버에서 메시지가 잘못 표시되었습니다. ParseFromArray를 호출하는 코드를 게시 할 수 있습니까? –
4 바이트 인코딩 된 메시지 크기 헤더가 빅 엔디안 인 것 같습니다 ... 수신자 측에서 빅 엔디안으로 정확하게 디코딩하고 있습니까? 올바른 N을 얻을 수 있기 때문에 올바르게 디코딩해야합니다. –
@James 헤더가 올바르게 디코딩되었으므로 인쇄 된 서버 버퍼가 인코딩 된대로 정확히 13 바이트임을 확인할 수 있습니다. – indiosmo