10

问题

我想通过 TCP 连接两个进程,但我不想指定其中哪个是服务器,哪个是客户端,但它们知道彼此的 IP 和主机。他们应该自己决定哪个是服务器,哪个是客户端,然后启动连接。

背景

我正在研究一个双向分布式框架 - 与 RPC 相比 - 没有客户端/服务器模型。相反,分布式组件应该能够通过指定主机和端口来相互通信。

编辑:这个概念超出了套接字连接的实现细节。这应该是一个新概念,以简化软件工程方面的分布式应用程序设计。这与 RPC 和 SOA(面向服务器/客户端)和面向消息的系统(需要使用 IMO 非直观模式)形成对比。

解决方案不得

  • 通过 UDP 定义协议,因为我需要 TCP 可靠性和 SSL 使用的可能性
  • 使用 ZeroMQ 之类的框架,因为我无法在目标平台上使用二进制包
  • 编辑:一个全局消息代理/名称服务器,因为它应该是一个轻量级的解决方案,没有额外的过程。添加这样一个节点只会重新引入客户端/服务器概念

更新

经过讨论,似乎只有一种有用的方法:每个对等点都需要一个列表套接字(或者您当然不能进行任何自动发现)。在连接请求中,如果还没有打开的连接,节点将尝试连接到另一个对等点。

如果连接是同时完成的,这可能会出现问题,因此我们最终会在两个对等方之间建立两个连接。现在的问题是如何在异步上下文中处理它。我认为这并不像下面评论中所说的那么简单,因为我们需要保证只关闭一个连接。我认为这项任务需要像 2PC 这样的协议。

4

2 回答 2

8

在我看来,你有点困惑。是的,软件工程文献讨论了服务器/客户端模型,并将其与其他模型(例如点对点)进行了对比。然而,在其核心,分布式系统总是最终在某处使用服务器/客户端模型,因为实际上没有其他方式可以通过 Internet 进行通信。

(从技术上讲,您应该能够通过 Internet 发送任何类型的 IP 数据报,因此您可以尝试发明一种不同的传输协议,其核心不是服务器/客户端,但我假设您不想安装新的传输层进入操作系统的网络堆栈,此外,还有其他陷阱,例如可能位于中间的家用 NAT 设备,会阻碍此类通信。)

如果您从一开始就限制所有类型的通信,这两个节点如何“在它们之间做出决定”谁来听和谁来连接?您只能通过 Internet 可靠地使用两种协议:UDP 和 TCP。它们都涉及设置侦听套接字的进程和另一个向所述侦听服务器发送消息(UDP)或执行连接尝试(TCP)的过程。

您在建立连接之前执行 UDP 消息的想法并没有真正改变任何事情。侦听 UDP 消息的进程仍然是服务器。如果有的话,它只是意味着除了侦听或启动 TCP 连接之外,所有节点也必须是 UDP 侦听服务器。

如果您不想在握手发生之前在对等方中拥有任何类型的侦听套接字,则您将需要某种第三方消息代理。这很明显,因为你不能在没有监听套接字的情况下进行通信,所以你一开始就不能执行所说的握手。第 22 条军规。

还有一个显而易见的解决方案:让每个对等点都监听连接,然后当两个对等点想要相互交谈时,让它们都尝试相互连接:如果两者都无法连接,则报告两个对等点都无法充当服务器。如果可以连接,请照常进行。如果两者都可以连接,则丢弃第二个连接并继续使用第一个连接。

我的建议是让您研究一下像 BitTorrent 这样的协议如何运作(它们的功能与我上面详述的解决方案非常相似)。或者,在您弄清楚这一点之后,您可能想要研究 NAT 穿越解决方案,例如STUN,以确保您不会经常遇到“两个对等方都不能成为服务器”的情况,但这是一个单独的问题。

于 2012-06-06T14:40:39.533 回答
2

如果你想让两个对等点找到对方,你要么必须调查:

  • 广播方案:zeromq 可以工作,但如果你不能使用它,你可以尝试使用 ip 多播
  • 您自己的发现服务

引导对等应用程序将需要上述之一。大多数人最终使用网络“广播”Bittorrent Tracker URL,然后帮助同行找到另一个。

鉴于您的要求,我强烈建议您研究 IP 多播。我使用 Twisted (http://twistedmatrix.com/documents/current/core/howto/udp.html) 创建了一个简单的 UDP 协议。我用它在我的桌面机器上启动了一个主进程,并在一组远程机器上启动了多个工作进程,以协调站点的负载测试。我不会说这是微不足道的,但它工作得很好。

关键是您必须定义自己的简单有线协议,可能是简单的网络字符串 (+)。我会使用像 JSON 这样的简单结构化消息格式来轻松序列化,并允许您轻松地在消息中编码元数据。

如果您使用 2 个 UDP 多播端口,一个用于发现,另一个用于您想要在节点之间发送的消息或数据,您将拥有更简单的时间。

我希望这会有所帮助,但如果没有更多关于你实际想要完成的细节,很难更具体。

于 2012-06-06T13:31:17.383 回答