点对点的去中心化网络 - 发送消息给所有节点

7
我需要创建一个无中央服务器的文件共享点对点网络。我阅读了很多相关信息,要求确保网络中的每个节点都保留其他节点的完整列表和网络上所有文件的完整列表。虽然我知道这不是最好的方法,但这是一个要求...另一个(在我看来很奇怪的)要求是节点之间的通信应该使用HTTP协议和JSON序列化。这意味着每个节点将充当Web服务器,并且还将有一种连接到每个其他节点的方法。因此,我想知道如何在没有单个节点直接连接到其他节点(连接太多)的情况下向所有其他节点传递消息的好方法。我一直在寻找一种方法来以某种方式路由消息几个级别,以便流量会有所分布。由于我可以了解并连接网络上的任何节点,因此我可以在发送消息之前有效地构建路由,然后告诉一些节点重新路由它。但是我如何找出最佳路线?如果有一个存在错误的节点无法重新路由消息会发生什么?

编辑:如果我没有表述清楚,我很抱歉。消息应该被网络上的所有节点接收到,而不仅仅是一个目标。

编辑2:您可以将我想要做的看作是一个网络服务器。它们应该能够分布式地保存数据(不是问题的一部分),但它们中的每一个都需要知道网络上可用的资源(哈希表)。客户端可以在其中一个服务器上上传文件(无论哪个都可以)。当这种情况发生时,其他所有人都需要知道此更改以更新其哈希表。如果新服务器加入网络,则同样适用。我的问题是如何传播此消息,而不必连接到所有其他服务器的单个服务器,这显然会在单个服务器上产生大量流量。


1
每个节点是否实际上都需要知道其他所有节点?如果是这样,为什么?大多数P2P系统只知道网络的一部分,它们必须要求其他节点帮助发现所需节点(例如,包含与搜索字符串匹配的文件的节点)。 - halfer
是的,这是一个要求。我知道这很奇怪。 - stormbreaker
如果您不让每个节点连接到网络上的每个其他节点,那么当一个节点加入(或离开)网络时,在该消息传播并且所有节点更新其本地节点列表之前会发生什么?当节点同时加入和离开网络(特别是在高速率下)时,我可以看到这可能会引起问题。 - user
如果某个时间点节点列表中包含了离线的节点,这并不是问题。这也是HTTP协议所面临的问题,因为我不能保持与所有节点之间始终打开的连接状态,所以必须实现某种ping机制来定期清理掉离线的节点。 - stormbreaker
需要进行扩展吗(它不会)并处理终端用户(它不会 - 多亏了NAT - 至少没有大量编程和中继超级节点的情况下)? - TomTom
显示剩余5条评论
1个回答

2

我看到你的问题分为两个部分:

没有中央服务器

现在流行的P2P实体是僵尸网络,它们有C&C服务器,并且也使用HTTP。它们倾向于通过使用某种算法来生成域名来利用DNS。您需要一些东西来种子/引导该过程,否则P2P平台将无法启动。演化可以通过传播来完成,也就是说,同伴可以从中央位置获取初始列表,然后随着从查询其他同伴中学到更多信息而建立DHT(即获得更多的响应)。

对于没有中央服务器的P2P网络,您可以执行本地网络扫描或使用零配置协议的实现,例如SSPD。这里的限制是您无法超出本地网络。例如,假设您想要跨越局域网进行多播,您将尝试到达哪些IP地址/范围?

发送消息给所有同伴

这不保证成功,因为在特定时刻您不知道哪些同伴处于活动状态,并且没有单个同伴拥有完整副本的DHT。通常使用洪泛的方式实现此目的。您可以采用查询洪泛策略,但不要期望得到回应。您可以在搜索时使用相同的策略,其中您实际上想要回答。如果您只想到达过去的5个级别,那么只需将哈希/ ID与计数器一起包含在内,然后同伴在传播消息之前递减计数器,并在计数器达到0时停止。

这个项目的一个大障碍是NAT。因此,不仅对等方需要知道彼此的外部IP和端口。如果您在局域网中,则这不是很大的问题。


是的,我会使用一些初始的节点列表来访问网络。不用担心NAT的问题。我将确保只有在客户端可以监听外部端口(如果没有NAT或upnp可以打开端口)时才能作为对等节点。此外,目标是能够在每个对等节点上保存完整的列表。但为了做到这一点,在发生更改时,我需要在所有节点上传播它们。我会研究查询泛洪技术,但问题是我不会对其他节点开放持久连接(因为它是HTTP),并且我将能够连接到任何我想要的对等节点。 - stormbreaker
我更新了我的问题并提供了更多的解释。感谢您的帮助。 - stormbreaker
如果您没有持久连接也没关系。客户端不可能保持与所有对等方的开放连接。每个对等方可以懒惰地/定期地检查其对等方列表是否仍然存活。尽管如此,查询洪泛是一种更有效的处理方式,因为每个对等方都可以查询一部分对等方,而如果单个对等方必须考虑每个人,那将会非常缓慢。 - Candide
1
不,查询洪泛不包括路由信息。然而,例如Kazaa会使用连接度量(带宽、延迟)来确定超级节点,并首先将消息路由到它们,然后再路由到较小的节点。即使在下载文件时,该协议也会首先选择超级节点。话虽如此,您需要决定对等方的邻域是什么。是整个世界还是仅同行的子集? - Candide
这有点像是个问题。每个节点都可以连接到任何其他节点,那么我如何决定哪些将成为相邻节点呢?也许是在已排序的服务器列表中选择最接近的服务器?但那么问题就是要选多少个呢? - stormbreaker
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接