我需要一个类Router来接收IP数据包,将其解析并发送给客户端(来自类Client)。当然,每个Client必须告诉Router他们要接收特定端口的数据包。

template <class T>
class Router
{
public:
    //Packets arrive from the world to a Client
    virtual bool onReceivePacket(Packet<T>::Ptr packet);
    //Packets arrive from a Client to the world
    virtual void onSendPacket(Packet<T>::Ptr packet);
protected:
    std::unordered_map<int, std::shared_ptr<Client>> tcpRoutingTable;
    std::unordered_map<int, std::shared_ptr<Client>> udpRoutingTable;
}


Router的界面非常简单。有人会用来自世界各地的数据包呼叫onReceivePacket,而Router会提取该数据包的目标端口,如果它是TCP或UDP,它将通过在客户端上调用onReceive相应地路由到客户端。例:

auto client = tcpRoutingTable.at(packet->tcpDestination());
client->onReceive(packet);


但是,有两件事困扰着我:

1)如何保持RouterClient之间的关系?如果我只是制作一个Client并将其订阅到Router,则Router还必须在Client中包含一个指向自身的指针。这种关系非常脆弱,就像ClientRouter消失一样,它将以不确定的行为结束。同样,通过在shared_ptrClient上简单地使用Router,我们得到了相互包含且因此永不消失的shared_ptr递归问题。

2)unordered_map是路由数据包的最佳方法吗?除了简单地检查整数并将其发送到特定客户端,我认为没有最快的方法。但是,第一个问题的答案米格斯改变了这种模式。

如您所见,Router是单线程的,因为用来自世界各地的数据包调用Router的东西也是单线程的。但是我可以受益于多线程吗?

最佳答案

考虑到您对设计目标和限制有更好的了解,以下是技术性答案-您强调简单性。


std :: weak_ptr可用于中断由std :: shared_ptr管理的对象形成的参考周期。


std::weak_ptr

由于您正在考虑并发性,因此请记住以下几点:实现了weak_ptr(Boost库)的前任直接表示,weak_ptr提供的操作子集非常有限,因为在多线程程序中访问其存储的指针通常很危险。您的std实现可能会继承相同的困难-请进行调查或在另一个问题中提问。


在内部,unordered_map中的元素根据其哈希值组织为存储桶,以允许直接通过其键值(平均平均时间复杂度恒定)直接访问各个元素。因此,从性能角度来看,unordered_map的使用很有吸引力。

09-10 04:05
查看更多