c - 如何绕过已连接的聚会

标签 c sockets asynchronous networking connection

根据我的程序架构,我很难确定如何取消双方的同步连接。这是一个P2P聊天。程序启动时,每一方都自动连接到另一方。连接过程是异步的。
当有传入连接时,将从侦听器调用信号,信号处理程序将处理该连接。所以“接受”也是异步的。
这将最终连接两个用户两次。将有两个连接。
双方都是服务器和客户端。这是不需要的。
现在我试了很多办法来解决这个问题,但没有一个真正奏效。
例如,我检查了侦听器信号处理程序,如果那个IP上的套接字已经存在,如果是这样,断开它并返回。但连接的设计方式是另一方将继续尝试连接。
正确的设计方法是什么?有哪些选择?

最佳答案

让我们看一个有四个同龄人的情况:
如果每个对等点都连接到其他对等点,则每对对等点之间将有两个连接。(如果有N个对等点,则有N(N-1)/2个唯一对。)
在上图中,对等点按其名称(A、B、C、D)排序。与字母表中后面有名字的对等点的连接是蓝色的,与字母表中前面的对等点的连接是红色的。
如果你能以某种方式命令同龄人,只有按顺序(红色)连接到自己之前的同龄人,并接受自己之后的同龄人的连接(红色),才能确保每对唯一的同龄人只有一个连接。
假设您有N同级,并且您以某种方式将它们从0排序到N-1,包括。然后,peeri需要从accept()节点连接到N-1-i节点。
当然,在实践中没有什么是那么简单的。问题是对等端可能在不同的时间出现,而不是同时出现;如果另一端还没有与地址和端口对应的侦听套接字,则连接将失败。所以,最重要的是先建立监听套接字,确保backlog足够大,然后再建立连接。
如果我们看看GIO GSockets(因为这似乎是OP正在使用的),解决方案相当简单,假设所有对等方都同意他们的顺序。
所有对等方都使用connect()ig_socket_new()g_socket_bind()创建侦听套接字。backlog应该至少是对等机的数量(少于一个)。
如果在运行时可以“邀请”新的同行,请使用较大的backlog。如果无法邀请新的对等方加入,则顺序中的最后一个对等方不需要侦听套接字,因为它将只进行连接,而不接受传入的连接。
g_set_backlog()th peer(第一个peer顺序为g_socket_listen())创建i套接字,以便在其之前按顺序连接到peer,使用0,可选地i,可选地g_socket_new()使连接不阻塞,并且g_socket_bind()
如果使用g_socket_set_blocking()使套接字非阻塞,则对等方可以在g_socket_connect()g_socket_set_blocking()中循环,以等待所有连接完成。
请注意,由于每个对等方创建其传入套接字的实际情况不同,连接可能会失败(因为另一端尚未启动)。在这些情况下,您只需重试;即再次调用g_socket_check_connect_result()
(也可以使用g_socket_condition_check()从套接字创建g_socket_connect(),将其视为事件源。)
此时,传入的连接应该被积压在操作系统网络堆栈中(或将被积压),因此peerg_socket_create_source()应该使用GSource来接受来自i对等方的传入连接,然后按顺序进行。
就我个人而言,我会使用不同的架构/方法,动态管理对等列表。
假设每个对等点都有一个唯一的标识符。(这可以是IPv6映射的地址和端口,也可以是用户昵称及其公钥。)
当建立连接时,连接方发送一个初始握手,该握手包含其自己的标识符以及它试图连接的一方的标识符。当接受新连接时,将接收到初始握手(在某个超时间隔内)。如果连接方是新的连接方,则将其添加到已连接对等方列表中。如果它已经连接,则新的或现有的连接被丢弃(发送一个包来说明掉落的原因)。
这也将允许“邀请”,并在网格上共享对等连接信息。

关于c - 如何绕过已连接的聚会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53794101/

相关文章:

c - for循环执行时间不同条件

c - 如何处理来自 term.h 的侵入性标识符?

c - MISRA-2012 违反规则 20.12 : misra_c_2012_rule_20_12_violation: macro parameter "val" is used in both expanded and raw forms

c - Datapipe.c TCP/IP 套接字重定向

javascript - 如何循环firebase的异步查询代码?

c - 结构 X 中的结构 X?

node.js - 如何在socket.io的房间中从客户端调用函数?

java - 除了socket.close()之外,还可以用其他方式关闭套接字吗?

Swift - 在没有完成处理程序的情况下同步执行大型 for 循环

c++ - 防止 sleep_for 阻塞后台线程