|
Peer-to-peer (P2P) computing is difficult enough without having to learn a new API. The first version of JXTA introduced us to P2P, but the API was tough to learn, and not easily mapped to our current process. But now, with the release of JXTA 2.0, you get your warm fuzzies back -- in the form of a ready-made API to wrap your P2P communications, with a socket-like interface and Java I/O streams. This article is a tutorial on how to use the new JXTA Socket API in JXTA 2.0. I'll also demonstrate a simple method for locating a person to chat with using a hash ID. With these two items and a little glue, you can create many different types of useful P2P applications. In a Nutshell: Understanding P2P and JXTAAre you new to P2P and JXTA? Simply put, P2P is just the interaction of two or more computers. However, the story is much more complex than a few cables. Firewalls, DHCP, and NAT devices hide the identity and addresses of computers and block direct communications. And since there are millions of computers and devices connected to the Internet, locating a specific device with a specific resource is not obvious and doubly complex because most devices are un-addressable and firewalled. JXTA and other P2P protocols are designed to solve these problems. JXTA is a P2P protocol specification that includes addressing, routing, messaging, and other services. JXTA creates a virtual network that overlays the mess of un-addressable and blocked computers with a uniform address space and network-level functions for discovering, grouping, and communication between PCs and devices. JXTA -- because it is a protocol -- is available in several languages and platforms, including the Java language and C++. Why P2P now? Hasn't P2P existed since two computers were networked? Today's massive numbers of connected devices with idle resources is a key reason P2P is currently on the rise. P2P computing can reduce your need for a large support infrastructure by substituting PCs in homes and businesses as resources, rather than centralized servers. Turning client-server programming upside down is not always straightforward, but the good news is that the techniques and API are getting simpler -- as you will see in the remainder of this article. The Chat Application
The example I'll be using is very simple;
Simple? In a way, it is, but JXTA (as demonstrated in this example) will let you accomplish a very complex task: Computers can "chat" all over the world, without the need for a server. The JXTA Socket APINow that you understand a little about our application, take a look at the classes in the JXTA socket package:
These classes should look familiar, since they're very similar to what is in the Java I/O package. The sequence of events is similar to sockets in the Deeper into JXTA Sockets
The classes
In addition, the
Figure 1 shows a user peer using
Figure 2 shows three users in our P2P chat network. Each user has a
Once the socket is connected, each peer has two streams. One is based on Starting JXTALet's now look at the example code. As mentioned, JXTA creates a virtual overlay network, so any application participating in the network needs to initialize its node, connect to the network, and announce its presence to others in the network. The initialization process is accomplished by joining the net peer group. The net group is the default groups all peers join when they connect to the JXTA network.
Line 2 of Listing 1 calls Note: Here is the code. The bulk of the classes are not shown, and some statements -- including exceptions, logging, and other nonessential code -- have been removed to improve readability.
Listing 1:
In addition to starting the JXTA platform, we also need to create a context for us to operate within. Line 3 creates a peer group ID using a utility class which converts a couple of strings ("hello world application" and "chat") to an MD5 checksum that is in turn is converted to a After calling this method, we are a part of the JXTA virtual network and ready to set up our socket. The Listening PeerTo create a socket, we need an ID that can be used to represent the chat user. In this case, we will create an ID that is the MD5 checksum of a name specified by the user. The ID is used in a similar way to an IP and port number for a traditional socket.
At line 2 of Listing 2, we specify the type of the pipe. The example uses the simple unicast type because we aren't worried about security. The pipe type can be either
In line 3, we create an ID based on the name, the type of pipe, and a string for a function, in this case
The class
Listing 2:
Waiting for Connections
The next thing to do is start the
Because this is a server socket, we need to wait for client peers to connect. Line 5 is where the
Listing 3:
The Chat CallerThe creation of the socket from the client side requires the same initial steps as for the server. We use the same initialization of JXTA, and the same strings to designate the peer group and pipe ID (line 3 of Listing 4) for the socket creation. In fact, all the code is the same for both the server and the client. Every peer starts a socket server and every peer can initiate a client-side connection. This may sound strange, but it's logical: any chatter can start the conversation with any peer that is listening.
On line 4, we create a pipe advertisement in the same way we did for the server socket. These advertisements must match, or the client peer will not be able to find the server. Line 5 initializes a Swing GUI window to display the chat messages. The
Listing 4:
Connecting and Waiting for Data
With everything set up, we can now connect to a server. The code is also set up to process an incoming connection. The code in Listing 5 sets up the I/O streams for either case. On line 3, we check to see if the value of
Remember that the
Listing 5:
Creating MD5 Checksum IDsEarlier, we created pipe and group IDs from MD5 checksums. As mentioned previously, a pipe ID is similar to an IP address and port number. We use the pipe ID because the address and port may not be visible due to a NAT or firewall. In addition, the IP address could be changed at any time by a DHCP server. The pipe ID signifies a logical address for connection, regardless of the true machine physical address or its addressability. When there are multiple peers with the same pipe ID, the peer would be chosen randomly. This might seem odd at first, but some situations in P2P call for a random use of resources. A random ID is good if it's not important which computer you connect to. In our case, however, the intent is to connect to a very specific peer for a chat. For our pipe ID, we will be careful to create a unique ID. We'll use the user's unique email address, because we need a way to contact a specific person, and an ID that is known and predictable.
A checksum or hash is used to hide the email address and to ensure that our ID will work for a large or small email address string. We always get the same length encoding for any length string. We are using MD5 hashing in this example because we can fit it into the
There are several ways to create a predictable ID. We can create a specific ID using
To create a seeded The method in Listing 6 creates the MD5 hash from two strings, which it concatenates.
Listing 6:
In Listings 7 and 8, the
Listing 7:
Listing 8:
In the future, instead of the MD5 checksum, we could use the Overview of the P2P Chat Application
Our chat application is simple. The point of the application is just to demonstrate how to use The design defines the following classes:
Figure 3 shows the classes in the application. The classes in the JXTA socket package are in blue.
How JXTA Works: Putting It All Together
The big difference between the It appears that computers are all connected via the web of the Internet. In truth, there are many barriers to direct connection. The obvious barriers are firewalls and NATs. The firewall usually blocks inbound traffic. We can still use the web, however, since the HTTP protocol is filtered so that we receive data based on requests. For each outbound request, the firewall allows in the corresponding response. The NAT presents a similar problem by hiding the IP address of computers in a local net and replacing it with one external address. The NAT is used by most companies and Internet service providers. Most home network connections are through one or more NAT devices. What about security? The only conversations that can occur when the user is behind the firewall is when the user (or software) initiates them. This is identical to a browser application. The layer of security provided by the firewall is not breached. How do any two computers isolated by firewalls talk to each other? The key is that a third peer is involved that acts as a relay. Each computer contacts the relay to collect messages or leave them to be accessed by the other computer. This is identical to what happens with HTTP tunneling, but with one little twist: The relay computer is just another PC someplace on the Internet. And the significance is that you don't need to have a server to have two computers talk to each other. In addition to HTTP, JXTA also supports TCP. If peers can access each other directly, there is no need for a relay peer. This means, of course, a much faster throughput.
Firewalls are not the only problem. DHCP can also cause problems by periodically changing the IP address of the computer. For the JXTA socket API, there is an additional ID called a pipe ID. The pipe ID acts as the socket's virtual address and port number. JXTA's routing system connects computers that are attempting to connect with the same pipe ID. For example, if a peer opens the Here is a summary of what happens to connect two computers:
The routing between A and B calculates what relays to use, or directly connects the two computers on the same network. To learn more about the magic of JXTA, refer to the JXTA documentation and books at the www.jxta.org web site. Summary and Final ThoughtsIn this article, you've seen how to create a simple socket application running in JXTA's P2P network. I also covered a simple way to address these sockets, using an MD5 checksum, which replaces the notion of an IP and port number. As JXTA technology continues to mature, we should expect to see a closer integration of JXTA with standard J2SE Java APIs. JXTA 2.0 is now easier, faster, stable, and ready for primetime. It's also already being used for many commercial applications. JXTA is a community and a new world we can explore together, so email me and let me know about the JXTA applications you're working on. About the AuthorDaniel Brookshier is the lead author and editor of JXTA: Java P2P Programming. He is a hands-on Java architect concentrating on JXTA, J2EE, Swing, and mentoring. Daniel is an independent consultant with clients in multiple industries, including such well known companies as Boeing, Ericsson, and Wal-Mart. ResourcesCode for this article and other related info Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Have a question about programming? Use Java Online Support. | |||||||||||||||||||
Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.
|
| ||||||||||||