我需要一个类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)如何保持Router
和Client
之间的关系?如果我只是制作一个Client
并将其订阅到Router
,那么Router
还必须在Client
中包含一个指向自身的指针。这种关系非常脆弱,好像Client
或Router
消失时,它将以不确定的行为结束。此外,只需在shared_ptr
和Client
上同时使用Router
,我们就会得到shared_ptr
相互递归且永不消失的递归问题。
2)unordered_map
是路由数据包的最佳方法吗?除了简单地检查整数并将其发送到特定客户端,我认为没有最快的方法。但是,第一个问题的答案就改变了这种模式。
如您所见,Router
是单线程的,因为使用来自世界的数据包调用Router
的事物也是单线程的。但是我可以受益于多线程吗?
答案 0 :(得分:1)
以下是一些技术性的答案,考虑到您更了解设计目标和限制-强调简洁性。
由于您正在考虑并发性,因此请记住以下几点:实现了weak_ptr(Boost库)的前任直接表示weak_ptr提供的操作子集非常有限,因为在多线程程序中访问其存储的指针通常很危险 。您的std实现可能会继承相同的困难-请进行调查或在另一个问题中提问。