我现在正在写一个简单的在线游戏,几个玩家可以一起玩,有一个集中的UDP服务器。我使用Google Protobuf 3进行数据包/消息的(反)序列化。目前,我在确定客户端传入数据包的类型时遇到问题。如何在C++中做到这一点?
在服务器端(Java),我可以使用以下代码来实现这一点:
private Message parseArbitraryPacket(byte[] data) throws InvalidProtocolBufferException {
Any any = Any.parseFrom(data);
for (Class<Message> packetType : listeners.keySet())
if (any.is(packetType))
return any.unpack(packetType);
return null;
}
其中listeners
是映射Message
类的Map
(例如KeepAlive.class
) 到相应的侦听器(例如KeepAliveListener
)。
这就是我如何将数据包从服务器(Java)发送到客户端的方式:
public boolean sendPacket(InetAddress targetAddr, Message packet) {
try {
byte[] data = Any.pack(packet).toByteArray();
srv.getUdpServer().send(new DatagramPacket(
data, data.length, targetAddr, srv.getConfig().getUdpServerPort()));
return true; // success
} catch (IOException ex) {
log.error("Failed to send a {} packet to {}.",
packet.getClass().getName(), targetAddr.getHostAddress());
log.error("Details:", ex);
return false; // failure
}
}
其中srv.getUdpServer()
是一个DatagramSocket
——服务器本身。
我现在如何在C++客户端中接收不同类型的数据包(我知道如何解析特定类型的数据包,例如KeepAlive
,但如果我不知道我收到了哪种类型的数据包怎么办?C++中甚至还有那种Any
类型吗?我找不到它。
PS:我在这里找到了Java中的
。Any
类型
在C++端,您可以执行以下操作。
包括
#include <google/protobuf/any.pb.h>
还有"消息"的相应头文件。
google::protobuf::Any any;
any.ParseFromString(/* put your byte[] data here */);
Message msg;
if (any.UnpackTo(&msg)
{
// successfully unpacked to Message type
// do rest of code here
}
else
{
std::cerr << "Unknown request typen";
}