Peer-to-Peer-Anwendungen leicht gemacht

Es wurde gesagt, dass Kazaa, die Peer-to-Peer-Anwendung (P2P) für die gemeinsame Nutzung von Dateien, mehr Netzwerkverkehr verursacht als jede andere Anwendung. Die Kazaa-Website gibt an, dass mehr als 385.000.000 Downloads stattgefunden haben! Zum Vergleich habe ich mir die Top-Downloads von Download.com angesehen, in denen Ad Aware mit nur 117.000.000 Downloads als beliebtester Download aufgeführt ist. Aus den 25 besten Downloads von Download.com habe ich 11 P2P-Anwendungen erkannt. Allein aufgrund dieser Beobachtungen werden P2P-Anwendungen offensichtlich immer beliebter. Die Dateifreigabe ist jedoch nicht die einzige Art von P2P-Anwendung. Die meisten Vorgänge einer typischen Instant Messaging-Anwendung sind P2P. Andere Beispiele sind Foren und verteilte Datenbanken. Und die Liste wächst einfach weiter.

Um solche P2P-Anwendungen zu erstellen, müssen Sie über Mittel verfügen, um andere Peers zu erkennen und mit ihnen zu interagieren. Die meisten Schwierigkeiten beim Erstellen von P2P-Anwendungen hängen mit der Aufrechterhaltung des Peernetzwerks, dem Formatieren und Weiterleiten von Nachrichten, dem Erkennen anderer Peers und ähnlichen Problemen zusammen. Project Jxta und seine Java-Bindung behandeln diese Aspekte Ihrer Anwendung. Mit Jxta können Sie sich auf Ihre Anwendung konzentrieren, nicht auf allgemeine P2P-Probleme.

Jxta ist eine verkürzte Version des Wortes nebeneinander,was bedeutet, nebeneinander. Das Jxta Programmer's Guide definiert Jxta als "offene Computerplattform für P2P-Computer". Es ist weder für eine Plattform noch für eine Programmiersprache spezifisch. Es wurde bei Sun Microsystems konzipiert und für die Open Source-Community freigegeben, um es zu pflegen und zu erweitern. Zusammen mit der Veröffentlichung wurde eine erste Java-Implementierung veröffentlicht. Ich konzentriere mich in diesem Artikel auf diese Implementierung, während ich die Verwendung von Jxta in einer Java-Umgebung diskutiere. Ich beschreibe auch die sechs häufigsten Vorgänge von Jxta-Anwendungen, die in Java implementiert sind, und stelle die Tools vor, die Sie zum Schreiben Ihrer eigenen P2P-Anwendungen benötigen. Nach dem Lesen dieses Artikels hoffe ich, dass Sie erkannt haben, wie einfach und aufregend es sein kann, P2P-Anwendungen zu erstellen. P2P-Anwendungen werden nicht nur an Popularität, sondern auch an Vielfalt weiter zunehmen.und die Entwickler von morgen müssen diese Technologien heute lernen, um auf dem neuesten Stand zu bleiben.

Java und Jxta

Der erste Schritt zur Verwendung von Jxta ist das Herunterladen von der Jxta-Downloadseite. Wie die meisten Leser zustimmen, kann es manchmal schwierig sein, Open Source-Projekte zu erwerben und für die Verwendung zu konfigurieren. Jxta ist ein Beispiel für ein großartiges Open Source-Projekt, das auch sehr einfach heruntergeladen und sofort verwendet werden kann. Wenn Sie Schwierigkeiten haben und weitere Informationen zum Herunterladen und Verwenden von Jxta benötigen, lesen Sie das Jxta-Programmierhandbuch.

Wenn Sie eine Jxta-fähige Anwendung zum ersten Mal in einem neuen Verzeichnis ausführen, wird Ihnen der GUI-Konfigurator bereitgestellt.

Was genau ist ein Peer? Laut Daniel Brookshire (einem bekannten Jxta-Committer und sogenannten "Champion") handelt es sich um einen "virtuellen Kommunikationspunkt", an dem verschiedene Peers auf demselben Gerät ausgeführt werden können. Das Gerät ist nicht auf einen PC beschränkt. Es kann sich um ein Mobiltelefon, einen Server oder sogar um einen so einfachen Gegenstand wie einen Sensor handeln. Es gibt spezielle Kollegen, die beiden, die wir beachten müssen, sind Rendezvous und Relay. Ein Rendezvous-Peer ermöglicht es Peers, außerhalb des Bereichs des lokalen Subnetzes zu kommunizieren, und ein Relay-Peer wird verwendet, um Informationen über Firewalls weiterzuleiten.

Lassen Sie uns zunächst die sechs häufigsten Jxta-Anwendungsvorgänge durchgehen, die in "Die Kosten für die Verwendung von Jxta" (IEEE Computer Society, September 2003) definiert sind. Sie sind unten in der Reihenfolge aufgeführt, in der sie normalerweise auftreten.

  1. Jxta starten: Das Starten von Jxta ist ziemlich einfach und nur eine Frage von wenigen Codezeilen.
  2. Beitritt zu einer Peer Group: Eine Peer Group ist eine Gruppe von Peers mit gemeinsamen Interessen, die zusammen gruppiert wurden. In diesem Artikel beschreibe ich, wie man bestehenden Peer-Gruppen beitritt und neue erstellt.
  3. Anzeigen veröffentlichen: Anzeigen, einfach ausgedrückt, sind das, worum es bei Jxta geht. Jxta verwendet Werbung, um Peers, Peer-Gruppen und andere Ressourcen plattformunabhängig zu ermitteln. Ich werde später in diesem Artikel über das Lesen, Erstellen und Senden neuer Anzeigen sprechen.
  4. Öffnen einer Eingangsleitung: Eine Leitung ist ein Mechanismus, mit dem Peers miteinander kommunizieren. Die Rohre sind „virtuelle Kommunikationskanäle “ -Virtual dass Rohr Benutzer nicht wissen , der tatsächlichen Adresse des anderen Peer. Ich diskutiere die Verwendung von Pipes zum Senden von Nachrichten im Abschnitt über Pipes in diesem Artikel.
  5. Andere Peer-Ressourcen entdecken: Bevor Sie mit anderen Peers kommunizieren können, müssen Sie zuerst einige finden, die ich auch diskutieren werde.
  6. Öffnen einer Ausgangsleitung: Ausgangsleitungen werden verwendet, um Nachrichten an andere Peers zu senden. Es gibt zwei Klassen von Ausgangsleitungen: Punkt-zu-Punkt oder Eins-zu-Eins und Ausbreitung oder Eins-zu-Viele.

Nachdem Sie nun wissen, wohin Sie dieser Artikel führen wird, beginnen wir unsere Reise.

Peer-Gruppen

Peer-Gruppen sind einfach eine Sammlung von Peers mit einer Reihe gemeinsamer Interessen. Peer-Gruppen können wie Peers Dienste bereitstellen, ein Peer-Group-Dienst ist jedoch nicht unbedingt von einem bestimmten Peer abhängig, der Anforderungen an ihn erfüllt. Solange ein einzelner Peer in der Gruppe den Dienst bereitstellt, ist der Dienst verfügbar. Jeder Peer ist Mitglied der World Peer Group und in der Regel auch der Net Peer Group und kann nach Belieben anderen Gruppen beitreten und diese verlassen. Was ist die Motivation für die Schaffung von Peer Groups? Hier einige Gründe:

  • Sichere Region pflegen: Wenn Sie eine sichere Peer-Gruppe haben, müssen Peers in der Gruppe ihre kritischen Informationen nicht offenlegen.
  • Gemeinsame Dienste bereitstellen: In der Regel möchten viele Peers dieselben Dienste wie andere Peers verwenden / bereitstellen. Daher ist es in der Gruppe nur sinnvoll, dies zu tun. Beispielsweise können Sie allen Peers in der Gruppe einen Drucker oder einen verteilten Datenbankdienst bereitstellen.
  • ID-Bereich einschränken: Rohrnamen werden mit der Gruppe abgeglichen, in der sie erstellt wurden. Wenn zwei Rohrleitungen denselben Namen haben, aber nicht in derselben Gruppe erstellt wurden, gibt es keine Probleme bei der Adressierung.

Lassen Sie uns untersuchen, wie wir eine Peer Group erstellen und dieser beitreten können. Die von der PeerGroupSchnittstelle bereitgestellten Methoden sind unten aufgeführt.

  • newGroup(Advertisement pgAdv): Wird normalerweise zum Instanziieren einer Gruppe verwendet, die bereits mit der erkannten Gruppenanzeige vorhanden ist
  • newGroup(PeerGroupID gid, Advertisement impl, String name, String description): Wird normalerweise zum Erstellen neuer Peer-Gruppen verwendet
  • newGroup(PeerGroupID gid): Wird verwendet, um eine vorhandene und veröffentlichte Peer-Gruppe nur mit der Peer-Gruppen-ID ( gid) zu instanziieren.

Peer-Gruppen erstellen

Das Erstellen einer einfachen Peer Group ist relativ einfach. Schauen wir uns einen Code an:

try { //We will create a new group based on the netPeerGroup so let's copy its //impl advertisement and modify it. ModuleImplAdvertisement implAdv = netPeerGroup.getAllPurposePeerGroupImplAdvertisement(); myPeerGroup = netPeerGroup.newGroup( null, //Create a new group id for this group. implAdv, //Use the above advertisement. "Group name", //This is the name of the group. "Group description" //This is the description of the group. );

System.out.println("---Peer group created successfully, id: " + myPeerGroup.getPeerGroupAdvertisement().getID() ); //Now that the group is created, it is automatically published and stored locally, //but we need to publish it remotely so other peers can discover it. discoveryService.remotePublish( myPeerGroup.getPeerGroupAdvertisement() ); System.out.println("---Published peer group advertisement remotely"); } catch (Exception e) { System.out.println("An error occurred"); e.printStackTrace(); }

Der Aufruf zum newGroup()Erstellen und Veröffentlichen der Gruppe im lokalen Cache. Höchstwahrscheinlich möchten Sie diese Anzeige beim Erstellen für andere Peers veröffentlichen, was Sie durch einen Anruf tun können remotePublish(). Diese Methode überträgt die Peer-Group-Werbung an andere Peers. Wenn Sie sicherstellen möchten, dass Sie die Werbung an Peers in einem anderen Subnetz senden, müssen Sie sicherstellen, dass Sie mit einem Rendezvous-Peer verbunden sind. Verwenden Sie dazu den folgenden Code, vorausgesetzt, Ihr Rendezvous-Peer ist aktiv und richtig konfiguriert:

private void connectToRdv(PeerGroup peerGroup) { if( rdv == null) { //Get the rdv service rdv = peerGroup.getRendezVousService(); } //Make sure that we are connected before proceeding while( !rdv.isConnectedToRendezVous() ) { try { Thread.sleep(5000); } catch (InterruptedException e1) { System.out.println("rdv connect interrupted"); e1.printStackTrace(); } } } 

Beitritt zu Peer-Gruppen

Der Beitritt zu einer Peer Group kann schwieriger sein, als tatsächlich eine zu erstellen. Selbst wenn wir eine ungesicherte Peer-Gruppe haben, müssen wir Anmeldeinformationen erstellen, Anmeldeinformationen leeren und diese Anmeldeinformationen an die Peer-Gruppe senden, der wir beitreten möchten.

Since we have a peer group advertisement, we need to create all the credentials necessary and join the group. Before we look at the joinGroup() method, let's look at one of the classes it uses, the MembershipService class. There are three methods in MembershipService that we are interested in, specifically apply(), join(), and resign(). We pass to the apply() method the type of authentication desired, and if that type is supported, it returns to us an Authenticator. We use this Authenticator to actually join the group. We pass it as an argument to the join() method, and it verifies our credentials. When a peer wants to leave a group, the call to resign() facilitates this.

Now let's look at the joinGroup() method:

private void joinGroup() { //Assuming myPeerGroup has been instantiated //before calling this method. System.out.println("Trying to join the peer group"); try { //Create the document that will identity this peer. StructuredDocument identityInfo = null; //No identity information required for our group.

AuthenticationCredential authCred = new AuthenticationCredential( myPeerGroup, //Peer group that it is created in null, //authentication method. ); MembershipService membershipService = myPeerGroup.getMembershipService(); Authenticator auth = membershipService.apply(authCred); //See if the group is ready to be joined. //Authenticator currently makes no distinction between //failed and unfinished authentication. if( auth.isReadyForJoin() ) { Credential myCred = membershipService.join(auth); System.out.println("Joined myPeerGroup"); System.out.println("Group id: " + myPeerGroup.getPeerGroupID() ); } else { System.out.println("Unable to join the group"); } } catch (Exception e) { System.out.println("An error occurred"); e.printStackTrace(); } }

Now that we have successfully joined the group, we are able to employ provided peer group services and send messages to the members. When developing P2P applications, thinking about where you want your peer group boundaries ahead of time will assist you in the long run. Keep in mind that peer group boundaries can span many networks.

The joining process can seem daunting at first, but it is pretty straightforward once you do it a few times. Now it is possible to employ many different methods to secure a peer group—the complexity of the joining process depends on the type of authentication desired. I do not discuss these methods here.

Pipes

As explained earlier, a pipe is a virtual channel of communication between two peers. Pipes can be confusing for beginners because newbies try to relate them to what they already know—sockets. While I discuss pipes, keep in mind that they are much more abstract then sockets.

In the most basic form, there are two types of pipes; input pipes and output pipes. Applications use input pipes to receive information, and output pipes, to send information. Pipes can be used in two addressing modes:

  • Unicast (point-to-point) pipes: These pipes connect one output pipe to a single input pipe, but a single input pipe can receive messages from different output pipes
  • Propagate pipes: These pipes connect a single output pipe to many different input pipes

Pipes are an unreliable, unidirectional, and asynchronous means of communication. Beefed-up implementations of pipes are available that provide reliability, bidirectional capabilities, and secure transit.

To create a pipe, first you must create a pipe advertisement and publish it. Then you need to get the pipe service from the peer group and use it to create the pipe. Each pipe has a pipe ID associated with it, which is used to address the pipe.

To create a new pipe ID, we use the IDFactory in the net.jxta.id package. Here is a sample of how to create and print the ID:

 ID id = IDFactory.newPipeID( peerGroup.getPeerGroupID() ); System.out.println( id.toURI() ); 

Note:peerGroup is the peer group for which you want to create the pipe.

Damit zwei Peers miteinander kommunizieren können, müssen sie die Pipe-IDs für die Pipes kennen, mit denen sie kommunizieren möchten. Es gibt verschiedene Möglichkeiten, um sicherzustellen, dass beide diese Informationen kennen:

  • Beide Peers lesen dieselbe Pipe-Ankündigung aus einer Datei
  • Die Pipe-ID ist in den Anwendungen fest codiert
  • Veröffentlichen und ermitteln Sie die Pipe-ID zur Laufzeit
  • Die Rohr-ID wird aus einer bekannten ID generiert