用C ++创建一个简单的分组路由器,如何跟踪“客户端”?

时间:2019-12-03 23:38:46

标签: c++ algorithm networking

我需要一个类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的事物也是单线程的。但是我可以受益于多线程吗?

1 个答案:

答案 0 :(得分:1)

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

  1. std :: weak_ptr 可用于打破由std :: shared_ptr管理的对象形成的参考周期。

std::weak_ptr

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

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