Skip to main content

skip to main content

developerWorks  >  Java technology  >

The practice of peer-to-peer computing: The P2P application framework

Getting down to the details

developerWorks
Document options

Document options requiring JavaScript are not displayed

Sample code


Rate this page

Help us improve this content


Level: Introductory

Todd Sundsted (todd-p2p@etcee.com), Chief Architect, PointFire, Inc.

01 May 2001

The best way to understand the technical side of P2P computing is to examine a real P2P application. This month, Todd Sundsted takes you on a tour of such an application. He describes how to install it, how to configure it, and how it works.

We're only one article into our trip through the landscape of P2P computing, and it's already time for a detour. Based on the reader feedback on "The practice of peer-to-peer computing: Introduction and history," I have realized that there is much more interest in using and understanding the P2P application than I anticipated. Originally, I had conceived of the application as a convenient source from which to draw examples to illustrate points being made in the text. It turns out that some of you want more detail, so that is what I'm going to provide this month.

Instead of continuing at the 1,000-foot level and addressing the question of security this month, I will instead drop to the 50-foot level for a tour of the application framework.

I sincerely hope that this detour with turn out to be more pleasant than those frequently encountered in real life.

Installation and execution

Let's begin with the nuts and bolts of installation. I've changed the process of starting the P2P application slightly because some readers encountered problems when starting the application last month.

Before you can run the P2P application, you must download two jar files -- p2p.jar and spp.jar -- and the configuration file app.properties (see Download). The file p2p.jar contains the class files for the P2P application itself. File spp.jar contains the class files for the messaging library used by the P2P application.

Once you have downloaded the files, add them both and the directory containing the configuration file to your classpath.

If you're running Windows, and you've downloaded the two jar files and the configuration file to the directory c:\p2p, set the classpath as follows:


  set CLASSPATH=c:\p2p\p2p.jar;c:\p2p\spp.jar;c:\p2p
	

If you're running Linux, Solaris, or some reasonable UNIX variant, and you've downloaded the two jar files and the configuration file to the directory /home/foo/p2p, set the classpath as follows:


  export CLASSPATH=/home/foo/p2p/p2p.jar:/home/foo/p2p/spp.jar:/home/foo/p2p
	

(The command above assumes you're running BASH as your command shell. I leave it up to you to figure out how to set environment variables in other popular shells such as CSH.)

Once the classpath is set, start the application with the following command:

  java com.etcee.app.ki.Main
	

The P2P application will greet you with a fancy informational banner and a command prompt.

One last note: my P2P application absolutely requires the Java 2 platform.



Back to top


The configuration file

The previous steps will get the P2P application up and running, but before you can use it profitably you must edit the configuration file. The configuration file defines the port the P2P application uses, the resources it controls, and the peers it recognizes. Listing 1 illustrates each of these definitions.


Listing 1. Example configuration file

  com.etcee.app.ki.port=7777
  com.etcee.app.ki.resource.0.name=share
  com.etcee.app.ki.resource.0.class=com.etcee.app.ki.resource.file.FileResource
  com.etcee.app.ki.resource.0.arg0=/home/foo/share
  com.etcee.app.ki.resource.1.name=tmp
  com.etcee.app.ki.resource.1.class=com.etcee.app.ki.resource.file.FileResource
  com.etcee.app.ki.resource.1.arg0=/tmp
  com.etcee.app.ki.peer.0=bass:7777
  com.etcee.app.ki.peer.1=salmon:7777
  com.etcee.app.ki.peer.2=perch:7777
  com.etcee.app.ki.peer.3=guppy:7777
		

The first section, consisting of a single line, defines the port the P2P application uses to receive connections from other peers. You will likely be able to leave this line as is.

The second section defines the resources the P2P application manages. You will probably need to edit this section. Listing 1 defines two resources, share and tmp. From the application's standpoint, resources are nothing more than instances of classes that implement the Resource interface, which we will examine shortly. A resource definition has the following general form:


Listing 2. A resource definition

  com.etcee.app.ki.resource.0.name=<name>
  com.etcee.app.ki.resource.0.class=<implementation class>
  com.etcee.app.ki.resource.0.arg0=<initialization argument>
  com.etcee.app.ki.resource.0.arg1=<initialization argument>
     .
     .
		

The name is the name given to the resource and is used to generate human-readable output. The class is the name of the Java class that is instantiated to create the resource. The P2P application dynamically loads and instantiates this class at run time. The argN arguments are passed to the newly instantiated resource during its initialization. The FileResource class uses these arguments to define the directory to serve files from, for example. You will need to edit the directory argument to point to a directory on your machine.

The third section defines the peers that the P2P application recognizes. Each line contains the name (or IP address) and port of a peer. Defining peers in this fashion is obviously not a scalable solution. In a future article we will look at better alternatives.



Back to top


The code

Outside of the SPP (Simple Point-to-Point) package that I adopted for peer-to-peer communication, the P2P application doesn't consist of many classes. Let's take a close look at the most important classes first and finish with a look at the SPP communication package.

Resource
The central component of the P2P application is the resource. In fact, the P2P application does little more than enable and control remote access to published resources. A resource can be anything addressable -- a filesystem, a phone book, a database, a directory. Every resource manages zero or more entries of the appropriate type (files for the filesystem resource, numbers for the phone book resource).

To illustrate the implementation of a resource, I created a simple filesystem resource class, FileResource, shown in Listing 3. The filesystem resource manages zero or more files.


Listing 3. The Resource interface

  public
  interface Resource
  {
    // The initialize() method requires a TTDFactory instance
    // (which the factory uses to create the TTDItem instances
    // it returns from the select() method in response to a
    // query) and a String array (which contains the arguments
    // from the configuration file).
    public
    void
    initialize(TTDFactory ttdfactory, String [] arstring)
    throws ResourceException;
    // The select() method requires a String instance that
    // defines the selection criteria.  It returns an array
    // of TTDItems, one for each entry that matches the
    // selection criteria.
    public
    TTDItem []
    select(String stringSelector)
    throws ResourceException;
  }
		

The structure and behavior of a resource is defined by the Resource interface. This interface defines the operations that may be performed on a resource. The list of operations currently includes select. Future implementations will include insert and delete as well.

The select() method takes as a parameter a string that defines the selection criteria. The method returns information about all of the resource entries that match the selection criteria. As currently implemented by the filesystem resource included with the P2P application, the selection string can either name an entry directly, in which case the resource returns the entry itself and its associated metadata, or the selection string can contain the wildcard "*", in which case the resource returns only the metadata for all of the entries it manages. More complex query languages are possible but are outside of the scope of this series.

Shell
The Shell class is little more than a very simple command-line user interface that enables users to browse local and remote resources. It uses the PeerReference, ResourceReference, and the ItemReference classes to send requests to other peers, but does little more than parse user input itself.

To better understand how communication works from the side of the requesting peer, let's take a look at part of the PeerReference class, shown in Listing 4.

Because I described user interaction with shell in detail last month, I won't repeat it here. Please stop for a moment and refamiliarize yourself with its operation before firing up the P2P application for the first time.

Communication
Communication between peers is what P2P is all about. Those of you who are familiar with the unbelievably primitive Napster protocol will understand why I selected something slightly more modern. I'm only going to speak briefly about SPP here. In a future article on P2P communication, I will describe it in more detail.

SPP models a message as a sequence of frames, as shown in Figure 1.


Figure 1. Message
A message as a sequence of frames

Each frame in a message has a type (indicated by its MIME type) and a body. A frame may optionally have headers that describe the data in the body.

The types of the frames in the sequence that constitute a complete and correct message are application dependent. Typically a message consists of a control frame followed by zero or more data frames. The data frame contains data referenced by the control frame. Our P2P application follows this pattern.

Messages occur in request/response pairs. A peer sends a request to another peer. That peer sends a response back to the first peer.

The control frame in a request message is the command frame. It contains the command and any parameters to the command. If any additional frames are present, they contain information needed by the command frame.

The control frame in a response message is the status frame. It contains the status (ok or error). If any additional frames are present, they contain information referenced by the status frame. In the case of requests to the filesystem resource, this information would consist of the contents of the selected file.

The advantage of the multiframe message model is that it allows rich messages to be exchanged between communicating applications. SPP is similar in many respects to BXXP.



Back to top


Conclusion

With understanding of the framework firmly within your grasp, we are now ready to continue with a discussion of P2P security next month. We will also integrate security support into our P2P application.




Back to top


Download

DescriptionNameSizeDownload method
Sample codej-p2papp.zip55 KBHTTP
Information about download methods


Resources



About the author

Todd Sundsted has been writing programs since computers became available in desktop models. Though originally interested in building distributed applications in C++, Todd moved on to the Java programming language when it became the obvious choice for that sort of thing. In addition to writing, Todd is cofounder and chief architect of PointFire, Inc. Contact Todd at todd-p2p@etcee.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top