How to Easily Make
Existing Java Software
Work on a Peer-to-Peer Network
Summary
This tutorial describes how to easily port over
existing Java network software which depends on java.net.Socket,
java.net.ServerSocket, and java.net.InetAddress to work on the Jxta
peer-to-peer network
Questions? Comments?
See the P2P Sockets Homepage
or contact Brad Neuberg at bkn3@columbia.edu. Feel free to call
him at 1-510-938-3263 (Pacific Standard Time, San Francisco) Monday
through Friday, not including weekends. Also see
his weblog, www.codinginparadise.org,
for Mozilla, Java, Jxta, and P2P news.
What is the P2P Sockets Project?
Are you interested in:
- returning the end-to-end principle to the Internet?
- an alternative peer-to-peer domain name system that bypasses
ICANN and Verisign, is completely decentralized, and responds to updates
much quicker than standard DNS?
- an Internet where everyone can create and consume network
services, even if they have a dynamic IP address or no IP address, are
behind a Network Address Translation (NAT) device, or blocked by an
ISP's firewall?
- a web where every peer can automatically start a web server, host
an XML-RPC service, and more and quickly make these available to other
peers?
- easily adding peer-to-peer functionality to your Java socket and
server socket applications?
- having your servlets and Java Server Pages work on a peer-to-peer
network for increased reliability, easier maintenence, and exciting new
end-user functionality?
- playing with a cool technology?
If you answered yes to any of the above, then welcome to the
Peer-to-Peer Sockets project! The Peer-to-Peer Sockets Project
reimplements Java's standard Socket, ServerSocket, and InetAddress
classes to work on a peer-to-peer network rather than on the standard
TCP/IP network.
"Aren't standard TCP/IP sockets and server sockets already
peer-to-peer?" some might ask. Standard TCP/IP sockets and server
sockets are theoretically peer-to-peer but in practice aren't for
several important reasons. First, many of the peers on the
Internet are given dynamic IP addresses through DHCP, shared or filtered
IP addresses through NAT devices, or IP addresses that are very hard to
reach due to firewalls. Creating server sockets under such
conditions is either impossible or requires elaborate application-level
ruses to bypass these restrictions. Second, TCP/IP sockets and
server sockets depend on the Domain Name System (DNS) to resolve
human-friendly host names into IP addresses. DNS is theoretically
semi-decentralized, but on an administrative level it is centralized
under ICANN, an unresponsive, non-innovative organization.
Further, standard DNS does not deal well with edge-peers that have
filtered or dynamic IP addresses, and updates take too long to
propagate and have no presence information. Developers who wish to
create exciting, new applications that extend DNS into new directions,
such as storing instant messaging usernames and presence info in DNS,
are stymied by the DNS systems technical and political issues.
The P2P Sockets project deals with these issues by re-implementing the
standard java.net classes on top of the Jxta
peer-to-peer network. Jxta is an open-source project that creates
a peer-to-peer overlay network that sits on top of TCP/IP. Ever
peer on the network is given an IP-address like number, even if they are
behind a firewall or don't have a stable IP address. Super-peers
on the Jxta network run application-level routers which store special
information such as how to reach peers, how to join sub-groups of peers,
and what content peers are making available. Jxta
application-level relays can proxy requests between peers that would not
normally be able to communicate due to firewalls or NAT devices.
Peers organize themselves into Peer Groups, which scope all search
requests and act as natural security containers. Any peer can
publish and create a peer group in a decentralized way, and other peers
can search for and discover these peer groups using other super-peers.
Peers communicate using Pipes, which are very similar to Unix
pipes. Pipes abstract the exact way in which two peers
communicate, allowing peers to communicate using other peers as
intermediaries if they normally would not be able to communicate due to
network partitioning.
Jxta is an extremely powerful framework. However, it is not an
easy framework to learn, and porting existing software to work on Jxta
is not for the faint-of-heart. P2P Sockets effectively hides Jxta
by creating a thin illusion that the peer-to-peer network is actually a
standard TCP/IP network. If a peer wishes to become a server
they simply create a P2P server socket with the domain name they want
and the port other peers should use to contact them. P2P clients
open socket connections to hosts that are running services on given
ports. Hosts can be resolved either by domain name, such as
"www.nike.laborpolicy", or by IP address, such as "44.22.33.22".
Behind the scenes these resolve to JXTA primitives rather than
being resolved through DNS or TCP/IP. For example, the host name
"www.nike.laborpolicy" is actually the NAME field of a Jxta Peer Group
Advertisement. P2P sockets and server sockets work exactly the
same as normal TCP/IP sockets and server sockets. For the
technically inclined and those who already understand Jxta, a table exists illustrating how the
standard TCP/IP concepts, such as host name, IP address, etc., map to
their Jxta equivalents.
The benefits of taking this approach are many-fold. First,
programmers can easily leverage their knowledge of standard TCP/IP
sockets and server sockets to work on the Jxta peer-to-peer network
without having to learn about Jxta. Second, all of the P2P Sockets
code subclasses standard java.net objects, such as java.net.Socket, so
existing network applications can quickly be ported to work on a
peer-to-peer network. The P2P Sockets project already includes a
large amount of software ported to use the peer-to-peer network,
including a web server (Jetty) that can receive requests and serve
content over the peer-to-peer network; a servlet and JSP engine (Jetty
and Jasper) that allows existing servlets and JSPs to serve P2P clients;
an XML-RPC client and server (Apache XML-RPC) for accessing and exposing
P2P XML-RPC endpoints; an HTTP/1.1 client (Apache Commons HTTP-Client)
that can access P2P web servers; a gateway (Smart Cache) to make it
possible for existing browsers to access P2P web sites; and a WikiWiki (JSPWiki)
that can be used to host WikiWikis on your local machine that other
peers can access and edit through the P2P network. Even better, all of
this software works and looks exactly as it did before being ported.
The P2P Sockets abstraction is so strong that porting each of
these pieces of software took as little as 30 minutes to several hours.
Everything included in the P2P sockets project is open-source,
mostly under BSD-type licenses, and cross-platform due to being written
in Java.
Because P2P Sockets are based on Jxta, they can easily do things that
ordinary server sockets and sockets can't handle. First, creating
server sockets that can fail-over and scale is easy with P2P Sockets.
Many different peers can start server sockets for the same host
name and port, such as "www.nike.laborpolicy" on port 80. When a
client opens a P2P socket to "www.nike.laborpolicy" on port 80, they
will randomly connect to one of the machines that is hosting this port.
All of these server peers might be hosting the same web site, for
example, making it very easy to partition client requests across
different server peers or to recover from losing one server peer.
This is analagous to DNS round-robining, where one host name will
resolve to many different IP addresses to help with load-balancing.
Second, since P2P Sockets don't use the DNS system, host names can
be whatever you wish them to. You can create your own fanciful
endings, such as "www.boobah.cat" or "www.cynthia.goddess", or
application-specific host names, such as "Brad GNUberg" or "Fidget666"
for an instant messaging system. Third, the service ports for a
given host name can be distributed across many different peers around
the world. For example, imagine that you have a virtual host for
"www.nike.laborpolicy". One peer could be hosting port 80, to
serve web pages; another could be hosting port 2000, for instant
messaging, and a final peer could be hosting port 3000 for peers to
subscribe to real-time RSS updates. Hosts now become decentralized
coalitions of peers working together to serve requests.
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 the
P2PSockets zip file 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.
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.
Overview of P2P Socket Classes
text
What to Change in your Code
text
How to Test your Changes
text
Limitations and Security Concerns
text
Resources
About the Author
Brad
"GNUberg" Neuberg is an open-source developer living in San
Francisco. He is currently involved with the BlackConnect project, an
effort to allow programmers to write Mozilla XPCOM components in Java;
the Java-Mozilla Integration
project, an umbrella effort for open-source developers to work on
turning Java into a full-fledged member of the Mozilla platform; the P2P Sockets project, an
initiative to port the existing web onto a peer-to-peer foundation and
make working with Jxta easier; the Paper Airplane project, a browser
plugin that empowers everone to be a writer as well as a reader; and
submissions to the Jxta and Mozilla projects. In the past
he has worked on the OpenPortal project and the Flash/Java Integration
project. He is an avid Java, C++, JavaScript, and Mozilla Platform
hacker who is a strong believer in usability. He has a B.A. in
Computer Science from Columbia University and experience building
enterprise trading systems for the securities industry using J2EE
technologies. He is now slightly older than he was when the
picture on the left was taken. Occasionally, after enough beers,
he'll start tap dancing.
This work is licensed under the
Creative Commons Attribution-NonCommercial License by Bradley Keith
Neuberg. To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc/1.0/ or send a letter to
Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.