一旦收到数据包,还有其他方法可以路由吗?
Are there other ways to route packets once received?
所以我正在为我的一个项目开发网络系统(一个游戏,如果这些信息是相关的。)我正在使用 tcpip v6 并且我已经决定基本上将数据包的格式设置为
2 bytes: Packet ID
2 bytes: Packet Length
n bytes: Payload
我认为可以选择 65k 个不同的数据包给了我足够的回旋余地,我无法想象数据包会变得比这更大(在游戏中,这有点愚蠢。)
目前,我有一个将 int 映射到函数对象的无序映射:
std::unordered_map<unsigned int, std::function<void(char*, unsigned int)>> Map =
{
{PID_NULL, PacketGetNull},
{PID_USER_INFO, PacketGetUserInfo},
{PID_LOGIN_FAILED, PacketLoginFailed},
{PID_PRESENT_CHAR_LIST, PacketPresentCharList},
{PID_PRESENT_WORLD_LIST, PacketPresentWorldList},
{PID_CHAT, PacketChat},
{PID_ADD_FRIEND, PacketAddFriend},
{PID_REMOVE_FRIEND, PacketRemoveFriend},
//...
};
而在处理数据包时,我基本上是这样做的:
unsigned short PacketID = 0;
unsigned short PacketLen = 0;
PACKET_READ(Packet, unsigned short, Pos, PacketID);
PACKET_READ(Packet, unsigned short, Pos, PacketLen);
auto Iter = Map.find(PacketID);
if (Iter != Map.end())
Iter->second(Packet, PacketLen);
else
printf("Error, packet type not found!\n");
是的,错误检查有点简单。这只是用于演示的示例代码。
但是,是的,还有其他方法可以根据数据包的 ID 来路由数据包吗?即使它们在技术上 没有更好,即使只是出于教育目的,即使知道替代方案也是很好的。
我建议您使用 array/vector 函数来避免(便宜?)调用 find 但设计与您已经使用的类似做(C 代码):
enum PacketID {
PID_NULL = 0,
PID_USER_INFO = 1,
/* ... */
PID_NUM_OF_IDS
};
void (*pkt_handler[])(char *, unsigned int) = {
PacketGetNull,
PacketGetUserInfo,
/* ... */
};
void HandlePacket(enum PacketID pkt_id, char *pkt, unsigned int pkt_len)
{
if (pkt_id >= PID_NUM_OF_IDS) {
printf("Error, packet type not found!\n");
return;
}
pkt_handler[pkt_id](pkt, pkt_len);
}
所以我正在为我的一个项目开发网络系统(一个游戏,如果这些信息是相关的。)我正在使用 tcpip v6 并且我已经决定基本上将数据包的格式设置为
2 bytes: Packet ID
2 bytes: Packet Length
n bytes: Payload
我认为可以选择 65k 个不同的数据包给了我足够的回旋余地,我无法想象数据包会变得比这更大(在游戏中,这有点愚蠢。)
目前,我有一个将 int 映射到函数对象的无序映射:
std::unordered_map<unsigned int, std::function<void(char*, unsigned int)>> Map =
{
{PID_NULL, PacketGetNull},
{PID_USER_INFO, PacketGetUserInfo},
{PID_LOGIN_FAILED, PacketLoginFailed},
{PID_PRESENT_CHAR_LIST, PacketPresentCharList},
{PID_PRESENT_WORLD_LIST, PacketPresentWorldList},
{PID_CHAT, PacketChat},
{PID_ADD_FRIEND, PacketAddFriend},
{PID_REMOVE_FRIEND, PacketRemoveFriend},
//...
};
而在处理数据包时,我基本上是这样做的:
unsigned short PacketID = 0;
unsigned short PacketLen = 0;
PACKET_READ(Packet, unsigned short, Pos, PacketID);
PACKET_READ(Packet, unsigned short, Pos, PacketLen);
auto Iter = Map.find(PacketID);
if (Iter != Map.end())
Iter->second(Packet, PacketLen);
else
printf("Error, packet type not found!\n");
是的,错误检查有点简单。这只是用于演示的示例代码。
但是,是的,还有其他方法可以根据数据包的 ID 来路由数据包吗?即使它们在技术上 没有更好,即使只是出于教育目的,即使知道替代方案也是很好的。
我建议您使用 array/vector 函数来避免(便宜?)调用 find 但设计与您已经使用的类似做(C 代码):
enum PacketID {
PID_NULL = 0,
PID_USER_INFO = 1,
/* ... */
PID_NUM_OF_IDS
};
void (*pkt_handler[])(char *, unsigned int) = {
PacketGetNull,
PacketGetUserInfo,
/* ... */
};
void HandlePacket(enum PacketID pkt_id, char *pkt, unsigned int pkt_len)
{
if (pkt_id >= PID_NUM_OF_IDS) {
printf("Error, packet type not found!\n");
return;
}
pkt_handler[pkt_id](pkt, pkt_len);
}