Во встроенных полях сообщений используется проводной тип 2: длина ограничена.
Это означает, что кодируется так:
<varint tagAndType> <varint messageLength> <theSize> <theInstanceId> <theMsgType>
Где varint
- это вариация base-128, как определено в спецификации кодирования protobuf .
Это означает, что theSize
не имеет фиксированного смещения от начала сообщения. Чтобы сделать вещи проще, вы можете отправить общий размер сообщения, прежде чем отправлять само сообщение. то есть, получено сообщение, подобное этому:
message PsdAgentMsg {
message Header {
uint32 theInstanceId = 2;
Type theMsgType = 3;
}
Header theHeader = 1;
oneof theMsg {
int32 abc = 2;
string def = 3;
double ghi = 4;
uint32 klm = 5;
PsdAgentGPCMsg theGPCMsg = 6;
}
}
Вы можете отправить ваши данные примерно так:
PsdAgentMsg msg;
fillOutMessageFields(msg);
std::string encoded_msg = msg.SerializeAsString();
uint32_t size = msg.size();
// First send the message size as a fixed-size integer
size = htonl(size);
send(sockfd, &size, sizeof(size), 0);
// Then send the message itself
send(sockfd, msg.c_str(), msg.size(), 0);
Тогда вы можете прочитать это на другом конце, как это:
// Read the size
uint32_t size;
rc = recv(sockfd, &size, sizeof(size), 0);
assert(rc == sizeof(size)); // Or proper error handling
size = ntohl(size);
// Read the actual message
std::string encoded_msg(size, '\0');
rc = recv(sockfd, &encoded_msg[0], size, 0);
assert(rc == size); // Or proper error handling
// Parse the message
PsdAgentMsg msg;
msg.ParseFromString(encoded_msg);