避免在P2P网络架构中同时进行双向连接[关闭]

问题描述 投票:-3回答:1

好吧,我是一名经过认证的程序员,多年来一直在做着各种各样的奇迹,但我终于要问一个我完全无法解决的问题。经过这么多年,我希望Stack Overflow能再次挽救我的生命。


这是关于独特的对问题。我正在使用GIO的GSocketClientGSocketService高级API来建立异步连接并接受两个对等体之间的传入连接(显然每个都使用相同的程序)。由于对等体可以同时相互连接,因此产生2个连接,而只需要一个连接。

我尝试了太多的事情,包括丢弃绑定IP数量的连接先于另一个连接(这样一个连接被丢弃)但是这仍然不能正常工作,所以我的脑袋现在旋转了什么,哪里应该先来。

为了不使我尝试的所有事情过于复杂化,我将直截了当地问:在这种情况下,正确的方法是什么?

c sockets networking p2p gio
1个回答
2
投票

这是艰难的,但经过3天的持续思考和测试......我有一个解决方案。

我坚信这个问题不应该被低估(特别是因为它似乎是“自命不凡和浮夸”),但我们不能总是得到最好的S / O。

问题

当两个对等体想要同时相互连接时,将有两个连接,而只需要一个连接。当接受,连接和处理是异步的并且可以在任何时间发生并且两个对等体分别使用相同的程序时,它甚至更复杂,因此是相当严格的P2P体系结构。这是拜占庭将军问题的典型例子,这是最困难的计算机问题之一。

解决方案

该解决方案不涉及完全同步,因此它缺乏异步连接,接受和处理的要点,并且在处理完成后不需要丢弃连接。这个有效的解决方案背后有三个主要的想法。

  1. 某种记录(我使用GList)来包含“待定”的IP
  2. 将IP转换为数字的功能
  3. 系统等待并给予权限

如果正确实施并在正确的地方使用,您就拥有它。现在再详细一点。

包含“待定”IP的某种记录

正如我所说,这可以是一个清单。必须通过互斥锁锁定追加,搜索和删除操作。在搜索之后和断开连接通知程序中,必须在接受时从列表中删除IP。

将IP转换为数字的功能

例如rScanf = sscanf(ip, "%u.%u.%u.%u", &bytes[0], &bytes[1], &bytes[2], &bytes[3]);

然后添加每个号码。这被用作独家标准。 if(remote_ip_number > local_ip_number)只会对其中一个同行真实。

系统等待并给予权限

连接必须等待接受线程的许可。尽管调用必须是阻塞,但它不会导致任何开销,在大多数情况下它会立即返回。如果它接收到许可(拒绝(1)或授予(2)),它将发送ACK(3)并返回(1- drop连接)或继续。主机等待ACK然后以相同的方式返回(丢弃连接)或继续(如果授予了权限)。

主持人应根据排他性标准确定是否拒绝或授予。首先,它检查待处理连接列表中是否存在IP(基本上意味着程序也尝试连接),如果存在,则IP条件匹配发送授权或拒绝否则。


重要的是,在实际尝试连接之前,在连接的同步调用的早期将IP添加到挂起连接列表中,并且重要的是程序的构造方式首先它连接到它想要的任何人。连接然后主机,以便注册第一个待处理的IP。这提供了可预测性的轻微优势。

connect(PETER); /* adds PETER ip to listPending */
connect(JOHN); /* adds JOHN ip to listPending */

host(ME); /* Gives permission if IP does not exist in listPending or it does but local ip number < remote ip number */
© www.soinside.com 2019 - 2024. All rights reserved.