Ich möchte zwei Prozesse über TCP verbinden, aber ich möchte nicht angeben, welcher von ihnen der Server ist und welcher der Client ist, aber sie kennen IP und Host von einander. Sie sollten selbst entscheiden, welches der Server und welcher der Client ist und dann die Verbindung herstellen.
Ich arbeite an einem bidirektionalen verteilten Framework, wo - im Gegensatz zu RPC - kein Client / Server-Modell existiert. Stattdessen sollten die verteilten Komponenten nur miteinander kommunizieren können, indem sie einen Host und einen Port angeben.
Edit: Das Konzept geht über die Implementierungsdetails einer Socket-Verbindung hinaus. Dies sollte ein neues Konzept sein, um den Entwurf einer verteilten Anwendung in Bezug auf das Software-Engineering zu vereinfachen. Dies steht im Gegensatz zu RPC und SOA (die Server / Client-orientiert sind) und nachrichtenorientierten Systemen (die die Verwendung von unintelligenten IMO-Mustern erfordern).
Nach der Diskussion scheint es nur einen nützlichen Ansatz zu geben: Jeder Peer muss einen Listing-Socket haben (oder natürlich keine automatische Erkennung). Bei einer Verbindungsanforderung versucht der Knoten, eine Verbindung mit dem anderen Peer herzustellen, wenn noch keine Verbindung besteht.
Dies könnte problematisch sein, wenn die Verbindung gleichzeitig erfolgt, so dass wir zwei Verbindungen zwischen zwei Peers haben. Die Frage ist nun, wie man in einem asynchronen Kontext damit umgehen soll. Ich denke nicht, dass dies so einfach ist wie unten in den Kommentaren, weil wir garantieren müssen, dass nur eine Verbindung geschlossen ist. Ich denke, dass ein Protokoll wie 2PC für diese Aufgabe benötigt wird.
Es scheint mir, dass Sie leicht verwirrt sind. Ja, Software-Engineering-Literatur spricht über das Server / Client-Modell und vergleicht es mit anderen Modellen wie Peer-to-Peer. Im Kern verwenden verteilte Systeme jedoch immer irgendwo ein Server / Client-Modell, weil es wirklich keine andere Möglichkeit gibt, über das Internet zu kommunizieren.
(Technisch gesehen sollten Sie in der Lage sein, jegliche Art von IP-Datagrammen über das Internet zu senden, sodass Sie versuchen könnten, ein anderes Transportprotokoll zu erfinden, das nicht Server / Client ist, aber ich gehe davon aus, dass Sie das nicht tun Ich möchte neue Transport-Layer in die Netzwerk-Stacks der Betriebssysteme installieren. Darüber hinaus gibt es noch andere Fehlerquellen wie z. B. Home-NAT-Appliances, die diese Kommunikation verhindern könnten.)
Wie können die zwei Knoten "zwischen sich selbst entscheiden", wer wird zuhören und wer wird sich verbinden, wenn Sie alle Arten von Kommunikation von Anfang an einschränken? Sie können nur zwei Protokolle über das Internet zuverlässig verwenden: UDP und TCP. Bei beiden handelt es sich um einen Prozess, bei dem ein abhörender Socket eingerichtet wird und bei dem anderen eine Nachricht (UDP) gesendet oder ein Verbindungsversuch (TCP) an den Abhörserver ausgeführt wird.
Ihre Idee, UDP-Nachrichten vor dem Verbindungsaufbau zu machen, ändert nichts wirklich. Ein Prozess, der UDP-Nachrichten abgehört, ist immer noch ein Server. Wenn überhaupt, bedeutet dies nur, dass zusätzlich zu dem Abhören oder Initiieren einer TCP-Verbindung alle Knoten UDP-Listener-Server sein müssen.
Sie müssen einen Nachrichtenbroker eines Drittanbieters haben, wenn Sie vor dem Handshake keine abhörenden Sockets in den Peers haben wollen. Dies ist offensichtlich, da Sie ohne zuhörende Sockets nicht kommunizieren können, so dass Sie den besagten Handshake zunächst nicht ausführen können. Catch-22.
Es gibt auch die offensichtliche Lösung: Lassen Sie jeden Peer auf Verbindungen hören, und wenn zwei Peers miteinander sprechen wollen, versuchen Sie beide, sich miteinander zu verbinden: Wenn keine Verbindung herstellen kann, melden Sie, dass keiner der beiden Partner funktionieren kann ein Server. Wenn Sie eine Verbindung herstellen können, gehen Sie wie gewohnt vor. Wenn beide eine Verbindung herstellen können, verwerfen Sie die zweite Verbindung und verwenden Sie weiterhin die erste Verbindung.
Mein Vorschlag wäre, dass Sie sich damit beschäftigen, wie Protokolle wie die BitTorrent-Funktion funktionieren (sie funktionieren ganz ähnlich wie die oben beschriebene Lösung). Optional, nachdem Sie dies herausgefunden haben, möchten Sie vielleicht NAT-Traversal-Lösungen wie STUN betrachten, um sicherzugehen, dass Sie es nicht tun Ich werde nicht so häufig auf die Situation "Kein Peer kann ein Server sein" hinweisen, aber das ist ein separates Problem.
Wenn Sie möchten, dass zwei Peers sich gegenseitig finden, müssen Sie entweder nach beiden suchen:
Bootstrapping-Peer-to-Peer-Anwendungen benötigen eines der oben genannten. Die meisten nutzen das Web, um eine Bittorrent-Tracker-URL zu "übertragen", und helfen damit Peers, sich gegenseitig zu finden.
Wenn Sie Ihre Anforderungen erfüllen, empfehlen wir Ihnen dringend, sich mit IP Multicast zu beschäftigen. Ich habe Twisted (http://twistedmatrix.com/documents/current/core/howto/udp.html) verwendet, um ein einfaches UDP-Protokoll zu erstellen. Ich habe damit einen Master-Prozess auf meinem Desktop-Rechner und mehrere Worker-Prozesse auf einer Reihe von Remote-Maschinen gestartet, um einen Auslastungstest einer Site zu koordinieren. Ich werde nicht sagen, dass es trivial ist, aber es funktioniert ganz gut.
Der Schlüssel ist, dass Sie Ihr eigenes Simple-Wire-Protokoll definieren müssen, etwas als einfachen Netstring (+). Ich würde ein einfaches strukturiertes Nachrichtenformat wie JSON für die einfache Serialisierung verwenden und es Ihnen ermöglichen, Metadaten in Ihren Nachrichten einfach zu verschlüsseln.
Sie haben eine einfachere Zeit, wenn Sie zwei UDP-Multicast-Ports verwenden, einen für die Erkennung und den anderen für Nachrichten oder Daten, die Sie zwischen Knoten senden möchten.
Ich hoffe, dass das hilft, aber ohne weitere Details darüber, was Sie eigentlich erreichen wollen, ist es schwierig, viel spezifischer zu sein.
Tags und Links python sockets distributed-computing