Python 连接两个TCP套接字而不定义客户端/服务器角色 问题:

Python 连接两个TCP套接字而不定义客户端/服务器角色 问题:,python,sockets,distributed-computing,Python,Sockets,Distributed Computing,我想通过TCP连接两个进程,但我不想指定哪个进程是服务器,哪个进程是客户端,但它们知道彼此的IP和主机。他们应该自己决定哪个是服务器,哪个是客户端,然后启动连接 背景 我正在研究一个双向分布式框架,与RPC不同的是,它没有客户机/服务器模型。相反,分布式组件应该只能够通过指定主机和端口相互通信 编辑:这个概念超出了套接字连接的实现细节。这应该是一个新概念,可以简化分布式应用程序的设计。这与RPC和SOA(面向服务器/客户端)以及面向消息的系统(要求使用IMO非直观模式)形成对比 解决方案决不能

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

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

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

解决方案决不能
  • 通过UDP定义协议,因为我需要TCP可靠性和SSL使用的可能性
  • 使用像ZeroMQ这样的框架,因为我无法在目标平台上使用二进制软件包
  • 编辑:一个全局MessageBroker/name服务器,因为它应该是一个轻量级的解决方案,不需要额外的进程。添加这样的节点只会重新引入客户机/服务器概念
更新 在讨论之后,似乎只有一种有用的方法:每个对等方都需要一个列表套接字(当然,您不能进行任何自动发现)。在连接请求中,如果尚未打开连接,则节点将尝试连接到另一个对等节点


如果连接是同时进行的,这可能会有问题,因此我们将在两个对等方之间建立两个连接。现在的问题是如何在异步上下文中处理它。我认为这不像下面评论中说的那么容易,因为我们需要保证只有一个连接是关闭的。我认为这项任务需要一个类似2PC的协议。

如果你想让两个对等点找到对方,你必须研究以下两种协议之一:

  • 广播方案:zeromq可以工作,但如果不能使用,可以尝试使用ip多播
  • 您自己的发现服务
引导点对点应用程序将需要上述之一。大多数人最终使用网络“广播”Bittorrent跟踪器URL,然后帮助同龄人找到彼此

鉴于您的需求,我强烈建议您研究IP多播。我用扭曲的(http://twistedmatrix.com/documents/current/core/howto/udp.html)创建一个简单的UDP协议。我使用它在我的桌面计算机上启动一个主进程,在一组远程计算机上启动多个工作进程,以协调站点的负载测试。我不会说它是琐碎的,但它工作得相当好

关键是您必须定义自己的simple wire协议,可能是simple netstring(+)。我将使用简单的结构化消息格式,如JSON,以便于序列化,并允许您在消息中轻松编码元数据

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


我希望这会有所帮助,但如果没有更多关于你真正想要完成什么的细节,就很难更加具体

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

(从技术上讲,您应该能够通过Internet发送任何类型的IP数据报,因此您可以尝试发明一种不同的传输协议,它的核心不是服务器/客户端,但我假设您不想在操作系统的网络堆栈中安装新的传输层,另外,还有其他问题,例如家用NAT设备这可能是阻碍交流的中间部分。 如果您从一开始就限制所有类型的通信,那么这两个节点如何“自行决定”谁将侦听谁将连接?您只能通过Internet可靠地使用两个协议:UDP和TCP。这两个协议都涉及设置侦听套接字的进程,另一个则发送消息(UDP)或者执行到所述侦听服务器的连接尝试(TCP)

在建立连接之前执行UDP消息的想法实际上并没有改变任何东西。侦听UDP消息的进程仍然是一个服务器。如果有任何改变,这只意味着除了侦听或启动TCP连接之外,所有节点也必须是UDP侦听服务器

如果您不想在握手之前在对等方中拥有任何类型的侦听套接字,则需要有某种类型的第三方message broker。这是显而易见的,因为没有侦听套接字,您无法进行通信,因此您无法开始执行上述握手。第22条军规

还有一个显而易见的解决方案:让每个对等方监听连接,然后当两个对等方想要彼此通话时,让两个对等方都尝试彼此连接:如果两个对等方都无法连接,则报告两个对等方都无法作为服务器使用。如果一个对等方可以连接,则按正常方式进行。如果两个对等方都可以连接,则放弃第二个连接并继续nue使用第一个连接

我的建议是让您研究一下像BitTorrent这样的协议是如何工作的(它们的工作原理与我上面详述的解决方案非常类似)。或者,在您了解了这一点之后,您可能希望研究NAT遍历解决方案,以确保您不会遇到“任何一个对等方都不能成为服务器”的问题这种情况经常发生,但这是另一个问题。