Я использую Protobuf3 с C# для моего клиента & C++ для моего сервера, где .proto создаются из соответствующего компилятора protoc3. Я новичок в использовании буферов протокола Google, где в настоящее время я пытаюсь выяснить, как повторно разобрать полученные байты на моем сервере, которые были отправлены от моего клиента, чтобы вернуть его обратно в исходную версию google :: protobuf :: Message объект на моем сервере C++.Получение сообщения Protobuf3 по сети
Мой клиент посылает CodedOutputStream в C#:
public PacketHandler()
{
m_client = GetComponent<ClientObject>();
m_packet = new byte[m_client.GetServerConnection().GetMaxPacketSize()];
m_ostream = new BinaryWriter(new MemoryStream(m_packet));
}
public void DataToSend(IMessage message)
{
CodedOutputStream output = new CodedOutputStream(m_ostream.BaseStream, true);
output.WriteMessage(message);
output.Flush();
m_client.GetServerConnection().GetClient().Send(m_packet, message.CalculateSize());
}
Это, кажется, работает, то сообщение, которое посылается прямо сейчас является простой Ping сообщение, которое выглядит следующим образом:
// Ping.proto
syntax = "proto3";
package server;
import "BaseMessage.proto";
message Ping {
base.BaseMessage base = 1;
}
message Pong {
base.BaseMessage base = 1;
}
Мой BaseMessage выглядит следующим образом:
// BaseMessage.proto
syntax = "proto3";
package base;
message BaseMessage {
uint32 size = 1;
}
Мой план состоит в том, чтобы надеяться, что все мои мэсы ges из BaseMessage, чтобы в конечном итоге определить идентификацию конкретного сообщения. Как только я получу синтаксический анализ &, повторный анализ разобрался.
Полученное сообщение, что я получаю на мой C++ стороне сервера выглядит следующим образом: \ u0004 \ п \ u0002 \ б
При получении сообщения я пытающийся повторно анализировать с помощью объекта CodedInputStream, пытаясь проанализировать полученные байты.
PacketHandler::PacketHandler(QByteArray& packet, const Manager::ClientPtr client) :
m_packet(packet),
m_client(client)
{
//unsigned char buffer[512] = { 0 };
unsigned char data[packet.size()] = { 0 };
memcpy(data, packet.data(), packet.size());
google::protobuf::uint32 msgSize;
google::protobuf::io::CodedInputStream inputStream(data, packet.size());
//inputStream.ReadVarint32(&msgSize);
//inputStream.ReadRaw(buffer, packet.size());
server::Ping pingMsg;
pingMsg.ParseFromCodedStream(&inputStream);
qDebug() << pingMsg.base().size();
}
Здесь я немного не уверены в процессе, который нуждающейся быть сделано, чтобы повторно разобрать сообщение в конкретном сообщении. Я считаю, что если я использую BaseMessage, который расширяет все сообщения, которые позволят мне идентифицировать конкретное сообщение, чтобы я знал, какой из них нужно создать. Однако в этом текущем тесте, где я знаю, что это будет сообщение Ping, ParseFromCodedStream, похоже, не создает оригинальное сообщение. Мое рассуждение происходит во время моего qDebug(), pingMsg.base(). Size() не является правильным значением, которое было установлено на этапе отправки в моем клиенте C#.
Буферы протокола Google не формируют его сообщения, что делает его раздражающим для потока. В принципе, вы должны использовать что-то помимо GPB, чтобы разграничить одно сообщение от другого. Что-то вроде ZeroMQ очень полезно в этом отношении. Это более привлекательный способ сделать это, чем отправить размер сообщения - проще получить истинную синхронизацию между отправителем и получателем. – bazza