ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Introduction to the Peer-to-Peer Sockets Project
Pages: 1, 2, 3, 4

Requirements and Configuration

You must download and install the following software to develop and work with P2P Sockets.

  • JDK 1.4+
    P2P Sockets only works with versions of the JDK after 1.4, because P2P Sockets subclasses java.net.InetAddress. Prior to 1.4, this class was marked final and could not be subclassed.

  • Ant 1.5.3+
    Used to both build and run P2P Sockets and extensions such as Jetty and Jasper.

  • P2PSockets-1.0-beta1.zip
    The latest release of the P2P Sockets package.

Install and configure the JDK and Ant, and make sure both are in your path so they can be run from the command line. Unzip P2PSockets-1.0-beta1.zip into the top level of your hard drive; spaces are not allowed in the directory names, or the P2P Sockets build files will not work correctly.

You must also add the JAR file p2psockets/lib/ant-contrib-0.5.jar to your CLASSPATH. On Windows this would look as follows:

set  CLASSPATH=%CLASSPATH%;c:\p2psockets\lib\ant-contrib-0.5.jar

The P2P Sockets directory already includes two different directories, test/clientpeer and test/serverpeer, that have JXTA configuration information already set up (these are in the hidden directories test/clientpeer/.JXTA and test/serverpeer/.JXTA, respectively). If you want to learn more about how to configure JXTA, read about the JXTA Configurator. The two test peers have already been configured for the worst possible case, which is that you are behind a firewall and a NAT device, which means you must use other intermediate peers to relay your requests; this configuration will work even if you are not under these conditions. One of the nice aspects about JXTA, though, is that this will all be transparent and hidden from you as you program and use the system.

When testing the examples in this tutorial, you must be connected to the Internet. This is for two reasons: first, the examples use a public JXTA server Sun has set up that helps bootstrap peers into the JXTA network; and second, on some operating systems (such as on Windows XP, by default), the network subsystem shuts down if you are not connected to the Internet, preventing client peers and server peers that are running on the same machine from finding or communicating with each other.

Creating a P2P Server Socket

Creating a P2P server socket is exactly like creating a normal java.net.ServerSocket:

// start a server socket for the domain
// "www.nike.laborpolicy" on port 100
java.net.ServerSocket server = new java.net.P2PServerSocket("www.nike.laborpolicy", 100);

This creates a server socket listening for client requests for the host www.nike.laborpolicy on port 100. Under the covers, the P2PServerSocket code searches for a JXTA peer group named www.nike.laborpolicy. If it finds this peer group, it joins it; otherwise it creates the group by publishing a JXTA peer group advertisement with the Name field formatted in a certain way. This field always has the format hostname/IP address, such as www.nike.laborpolicy/ We search based on host name or IP address on JXTA rendezvous servers by using wildcards, such as www.nike.laborpolicy/* to search without having to know the IP address, or */ to search for a peer group with the given IP address. Once we have found or created the host's peer group, we then publish a JXTA pipe advertisement into this peer group with the Name field set to the port number, such as <Name>80</Name>.

After creating this server socket, you can now treat it as an ordinary java.net.ServerSocket in your code, waiting for a client and then retrieving an InputStream and OutputStream from the client and communicating normally:

java.net.Socket client = server.accept();

// now communicate with this client
java.io.DataInputStream in = new DataInputStream(client.getInputStream());
java.io.DataOutputStream out = new DataOutputStream(client.getOutputStream());
out.writeUTF("Hello client world!");
String results = in.readUTF();

Even though the client looks like a normal java.net.Socket, it is actually connecting and communicating to your server through the JXTA peer-to-peer network, with requests and responses possibly being relayed by other peers to traverse NATs and network partitions. All of this is hidden from you, however.

Unlike normal server sockets, we need to initialize and sign into our peer-to-peer network. Before you can create the P2PServerSocket, therefore, you must sign in:

// sign into the peer-to-peer network, using
// the username "serverpeer", the password "serverpeerpassword",
// and create/find a scoped peer-to-peer network named "TestNetwork"
java.net.P2PNetwork.signin("serverpeer", "serverpeerpassword", "TestNetwork");

The first two arguments are the username and password to use when signing into the peer-to-peer network. These are entered by the user when they set up the JXTA Configurator, a Swing dialog (which will pop up the first time you run the JXTA platform) that allows you to configure your peer on the P2P network. In your own application, you might retrieve these values either from the command line or from a GUI. The P2P Sockets package comes preconfigured with two JXTA peers already configured, located in test/clientpeer and test/serverpeer.

The final value (TestNetwork, in the above example) is a unique name that will be given to your peer-to-peer network. Different peer-to-peer networks that are based on P2P Sockets can co-exist without knowing about each other. Clients and servers create and resolve their server sockets and sockets in a specific peer-to-peer network. The final value is the name of your own private, application-specific peer-to-peer network. If you create your server socket in the peer-to-peer network named TestNetwork while a client signs into another peer-to-peer network named InstantMessagingNetwork, then they will not be able to find each other or communicate.

Here's what is happening inside of the P2PNetwork class. When you call the signin method, the network string (TestNetwork in the example given) is hashed into an MD5 peer group ID; this ensures that the application name given is globally unique if we search based on the peer group ID. We then search for this peer group, and create it if it does not exist. All domain name and IP address resolutions now occur inside of this application peer group. Note that the default JXTA configuration files included in test/clientpeer and test/serverpeer are configured to use the Sun rendezvous servers to bootstrap into the JXTA network; you should configure your own peers differently if you want them to use a different beginning rendezvous server when bootstrapping into the JXTA Net Peer Group.

As a programmer, you will choose your network name to go along with the name of your application or the type of network you are creating, such as MyApplicationsNetwork or AcmeCompanyInformationNetwork.

The final code looks as follows:

import java.io.InputStream;
import java.io.OutputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.P2PServerSocket;
import java.net.P2PNetwork;

public class ExampleServerSocket {
   public static void main(String args[]) {
      try {
         // sign into the peer-to-peer network, 
         // using the username "serverpeer", the password "serverpeerpassword",
         // and create/find a scoped peer-to-peer network named "TestNetwork"
         System.out.println("Signing into the P2P network...");
         P2PNetwork.signin("serverpeer", "serverpeerpassword", "TestNetwork");

         // start a server socket for the domain
         // "www.nike.laborpolicy" on port 100
         System.out.println("Creating server socket for " + "www.nike.laborpolicy:100...");
         ServerSocket server = new P2PServerSocket("www.nike.laborpolicy", 100);
         // wait for a client
         System.out.println("Waiting for client...");
         Socket client = server.accept();
         System.out.println("Client Accepted.");
         // now communicate with this client
         DataInputStream in = new DataInputStream(client.getInputStream());
         DataOutputStream out = new DataOutputStream(client.getOutputStream());
         out.writeUTF("Hello client world!");
         String results = in.readUTF();
         System.out.println("Message from client: " + results);
         // shut everything down!

      catch (Exception e) {

Pages: 1, 2, 3, 4

Next Pagearrow