Last week we gave you some broad strokes about networking in Java. This week it's time to cover some of the details, and of course, the fine print. Back to Basics: Part Two
Basically, there are three network facilities available to you through the various classes in
java.net. The most familiar one we mentioned last week, based on the URLConnection object, allows you to send and receive HTTP, like a Web browser, by specifying a URL. But this is really heavily related to one of the other two classes of network connection: the socket. If you're not schooled in networking, you may have heard that term before and been mystified. Though it may sound obscure, it's really quite simple:
- Sockets can be thought of as the starting points for persistent, reliable network streams. Much as you might use a stream to read from or write to a file on your own computer, you can use one to do the same over the network interface. To an extent, you really can think of whatever program you connect to remotely as a file; the nature of this protocol (really TCP) insures that data being sent and received is error-free and that packets (the chunks your information is broken into when sent over the network) arrive in proper order. Anything lost is resent.
Web pages, telnet connections, and FTP connections, for instance, all use this protocol. It's now at your disposal.
- The Datagram, on the other hand, is just a name that's been given to a packet transmitted with a certain kind of protocol. Within the datagram model, there are no streams, just individual packets created directly by your program. This is a function of the datagram's approach being far more basic and low level than the socket's approach. There is nothing in the datagram system to insure that you get all your packets in order, or even at all. Nor is there anything in it to automatically break your data down into packets for you, or reassemble it when it arrives. This may seem byzantine, but if you need to have direct control over your network connection, this is the only way to go.
If your connection does not need to be 100% reliable, then it wouldn't even make sense to use sockets. If a single packet is lost in a chain of dozens of them, all the subsequent packets are held up until it can be resent. Applications that use this system want to define their own behavior when a packet doesn't get through. RealAudio is one example of such.
Before we jump into using these classes, though, let's examine their limitations. The most prominent drawback is that the Java networking capabilities have been very deliberately and severely hobbled. If you recall, the SecurityManager provided with Netscape (following the standard set by Sun) does not allow any network connections to a host other than the one the applet loaded from.
(applet source)
Above is an applet showing it's own
codeBaseanddocumentBase. Many months ago we mentioned the utility of these Applet methods in loading things from a server. This information is certainly useful for such things, but one of the primary goals of keeping it is to keep track of the single host with which the applet may communicate. Attempts to stray outside this pathway supposedly result in a security exception.In fact, there are several known bugs in this scheme, and to a greater or lesser extent it is possible to communicate with other hosts. Exactly how that's accomplished is outside the scope of this article, and we are assured Sun is working rapidly to correct all of the security problems associated with Java.
It may not even immediately be obvious why it's a risk to allow applets the privilege to speak with whomever they wish. There appear to be at least two good reasons for it, and the first has to do with how a firewall works.
Firewalls are designed to only allow specifically authorized information through from an outside network into an inside network. They provide security by keeping attackers from reaching your insecure machines, hopefully stopping them at the firewall itself, which (as the theory goes) is completely secure. But people behind a firewall, gripped in the recent frenzy of needing to surf the Web, don't want to be shut in, and firewalls are typically allowed to pass Web traffic (HTTP). Harmless, right?
Well, it was, during the brief time your Web browser was nothing more than a simple word processor that loaded its documents over the Web. With the advent of modern browser software, it's a different story. If there were no security restrictions on use of the network, it would be relatively simple to write a Java applet which, when loaded silently into a target machine, will act as a relay communicating (read: harassing) machines inside the firewall under direction of it's source host (or even some other host), via HTTP. Rather than unleash this potential security debacle on firewall owners everywhere (not to mention that Sun itself sells firewall products), Java engineers elected to eviscerate their own creation.
The second good reason for doing it was simpler: accountability. Regardless of what an applet does on your system, it can be very handy to be assured that it started with and ended with the hostname that you typed in when you were entering the last URL. It confines the applet to the relationship you expect--one between the Web server and the Web browser. It excludes the rest of the network universe.
Naturally, this makes networking between Java applets a entirely different ballgame, and sadly a number of utopian software engineer's dreams about vast peer-to-peer linked Web pages go up in smoke. But take heart, there's still a lot that can be done, and keep in mind that these restrictions only apply to Applets, not full-fledged Java applications.
Next week, we'll start with some examples.