收到后是否还有其他方式来路由数据包?

时间:2016-03-29 00:48:14

标签: routes network-programming packet online-game

所以我正在为我的项目工作网络系统(一个游戏,如果这些信息是相关的。)我使用tcpip v6并且我决定基本上有这个数据包& #39; s格式为

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来路由数据包?即使他们在技术上不是更好,但即使只是出于教育目的,即使知道替代方案也会很整洁。

1 个答案:

答案 0 :(得分:1)

我建议你使用一个数组/向量函数来避免(廉价?)调用 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);
}