我将 Protobuf3 与 c# 用于我的客户端和 c++ 用于我的服务器,其中 .proto 是从相应的 protoc3 编译器生成的。我是使用 Google Protocol Buffers 的新手,我目前正试图弄清楚如何重新解析从我的客户端发送的服务器上接收到的字节,以将其转换回它的原始 google::protobuf::Message我的 C++ 服务器上的对象。
我的客户正在 c# 中发送 CodedOutputStream :
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;
}
我的计划是希望从 BaseMessage 扩展我的所有消息,以便最终识别特定消息。一旦我弄清楚了解析和重新解析。
我在 C++ 服务器端收到的消息如下所示:\u0004\n\u0002\b
收到消息时,我试图通过解析接收到的字节来使用 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# 客户端的发送阶段设置的正确值。