我正在爲我的客戶端使用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