我正在为我的客户端使用Protobuf3和c#& C++用于我的服务器,其中.proto是从相应的protoc3编译器生成的。我是使用Google协议缓冲区的新手,目前我正试图弄清楚如何重新解析从我的客户端发送来的服务器上接收到的字节,以将其重新转换为它的原始google :: protobuf :: Message对象在我的C++服务器上。通过网络接收Protobuf3消息
我的客户端发送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;
}
我的计划是希望将所有messa基本消息中的ges以便最终识别特定的消息。一旦我得到解析&重新解析了。
,我在我的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#客户端的发送阶段中设置的正确值。
谷歌协议缓冲区没有框架它的消息,使它很烦人的流。基本上你必须使用GPB以外的东西来划分另一个消息。像ZeroMQ这样的东西在这方面非常有用。与发送消息大小相比,这是一种更有趣的方式 - 在发送者和接收者之间实现真正的同步更容易。 – bazza