c - 避免 P2P 网络架构中同时双向连接

标签 c sockets networking p2p gio

好吧,我是一名经过认证的程序员,多年来一直在创造各种奇迹,但我终于要就一个我完全无法解决的问题提出一个问题。我希望多年之后 Stack Overflow 能够再次拯救我的生命。

<小时/>

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

我尝试了太多的事情,包括删除绑定(bind)IP号在另一个之前的连接(以便一个连接被丢弃),但这仍然并不总是有效,所以我现在开始思考什么和哪里应该首先出现。

为了不让我尝试过的所有事情变得过于复杂,我会直接问:在这种情况下正确的方法是什么?

最佳答案

这很困难,但经过 3 天的坚持思考和测试..我找到了解决方案。

我坚信这个问题不应该被否决(特别是因为它似乎“自命不凡且浮夸”),但我们不能总是充分利用 S/O,不是吗?

问题

当两个对等点想要同时相互连接时 将有两个连接,而实际上只需要一个。 接受、连接、处理时就更复杂了 是异步的,可以随时发生,而且两者都可以 对等体分别使用相同的程序,因此具有相当严格的P2P架构。 这是拜占庭将军问题的典型例子,拜占庭将军问题是最难的计算机问题之一。

解决方案

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

  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) 仅对于其中一个对等方为 true。

等待并授予权限的系统

连接必须等待接受线程的许可。虽然调用必须是阻塞的,但它不会造成任何开销,大多数情况下它会立即返回。 之后,如果它收到许可(拒绝 (1) 或授予 (2)),它会发送 ACK (3) 并返回(1-断开连接)或继续。主机等待 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 */

关于c - 避免 P2P 网络架构中同时双向连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55187491/

相关文章:

c - 给出虚假值(value)的宏观方程?

c - 在 C 中将 memset 用于整数数组

c - 在 C 中构建具有固定大小 header 的 UDP 数据报

客户端关闭或客户端重启时,Java 服务器套接字 TCP 连接卡在 CLOSE_WAIT 状态

Java Dom实现LS

java - 两个线程可以同时使用同一个套接字吗?这可能会出现问题吗?

c - 如何使用 fread 从二进制文件中读取整数?

c - 在类 UNIX 操作系统上,二进制文件的最少内存使用量是多少?

perl - 如果子进程手动收割,则 IO::Socket::accept 仅有效一次

amazon-web-services - 具有 NAT 网关和 VPC PrivateLink : which one will be used? 的 AWS 私有(private)子网