This chapter serves as an introduction to the package containing Javas networking facilities. It covers the classes, interfaces, and exceptions that make up the java.net package.
Unless otherwise noted, classes, exceptions, and interfaces are members of the java.net package. The full package name will be given for members of other classes such as java.io.IOException. Method names will be shown followed by (), such as close().
These descriptions are not intended to be a complete reference. For a more detailed description of the components of the java.net package and the arguments of their various methods, see Appendix A, Java Language Summary.94"
The classes in the networking package fall into three general categories:
Keep in mind that some of the java.net classes (such as URLConnection and ContentHandler) are abstract classes and cannot be directly instantiated. Subclasses provide the actual implementations for the different protocols and contents.
The following table lists all of the classes in the package along with a brief description of what functionality each provides.
Table 28.1. Classes of the java.net package.
The description of each class is given in the following format:
The URL class represents a web Uniform Resource Locator. Along with the URLConnection class, this class provides access to resources located on the World Wide Web via the HTTP protocol or on the local machine through file: URLs.
The constructors for the URL class provide for creating absolute and relative URLs. There is a constructor that takes a whole String as a URL, as well as constructors allowing the protocol, host, and file to be specified in separate String objects. The class also provides for relative URLs with a constructor that takes another URL object for context and a String as the relative part.
The URL class provides methods for retrieving individual components of the represented URL (such as the protocol and the host name). It also provides comparison methods for determining if two URL objects reference the same content.
Probably the most important method is getContent( ). This returns an object representing the contents of the URL. There also is an openConnection( ) method that returns a URLConnection object that will provide a connection to the remote content. The connection object then can be used to retrieve the content, as with the getContent( ) method.
The URLConnection class does the actual work of retrieving content that is specified by URL objects. This class is an abstract class, and as such cannot be directly instantiated. Instead, subclasses of the class provide the implementation to handle different protocols. The subclasses know how to use the appropriate subclasses of the URLStreamHandler class to connect and retrieve the content.
The only constructor provided takes a URL object and returns a URLConnection object for that URL. However, because this is an abstract class it cannot be directly instantiated. Instead of using a constructor you probably will use the URL class openConnection( ) method. The Java runtime system will create an instance of the proper connection subclass to handle the URL.
The getContent( ) method acts just like the URL class method of the same name. The class also provides methods to get information such as the content type of the resource or HTTP header information sent with the resource. Examples of these methods are getContentType( ), which returns what the HTTP Content-Type header contained, and the verbosely named guessContentTypeFromStream( ), which will try to determine the content type by observing the incoming data stream.
Methods also are provided to obtain an InputStream object that reads data from the connection. For URLs that provide for output there is a corresponding getOutputStream( ) method. The remaining URLConnection methods deal with retrieving or setting class variables.
There are several protected members that describe aspects of the connection, such as the URL connected to and whether the connection supports input or output. A variable also notes whether the connection will use a cached copy of the object or not.
A Socket object is the Java representation of a TCP connection. When a Socket is created, a connection is opened to the specified destination. Stream objects can be obtained to send and receive data to the other end.
The constructors for the Socket class take two arguments: the name (or IP address) of the host to connect to, and the port number on that host to connect to. The host name may be given as either a String or as an InetAddress object. In either case the port number is specified as an integer.
The two most important methods are getInputStream( ) and getOutputStream( ), which return stream objects that can be used to communicate through the socket. A close( ) method is provided to tell the underlying operating system to terminate the connection. Methods also are provided to retrieve information about the connection such as the local and remote port numbers and an InetAddress representing the remote host.
The ServerSocket represents a listening TCP connection. Once an incoming connection is requested, the ServerSocket object will return a Socket object representing the connection. In normal use, another thread would be spawned off to handle the connection. The ServerSocket then is free to listen for the next connection request.
Both constructors take as an argument the local port number to listen for connection requests. A constructor is provided that also takes the maximum time to wait for a connection as a second argument.
The most important method is accept( ). This method will block the calling thread until a connection is received. A Socket object is returned representing this new connection. The close( ) method tells the operating system to stop listening for requests on the socket. Also provided are methods to retrieve the host name the socket is listening on (in InetAddress form) and the port number being listened to.
The DatagramSocket represents a connectionless datagram socket. This class works with the DatagramPacket class to provide for communication using the UDP protocol.
Because UDP is a connectionless protocol, you do not need to specify a host name when creating a DatagramSocketonly the port number on the local host. There is a second constructor which takes no arguments. When this constructor is used the port number will be assigned arbitrarily by the operating system.
The two most important methods are send( ) and receive( ). Each takes as an argument an appropriately constructed DatagramPacket (described in the following section). In the case of the send( ) method, the data contained in the packet is sent to the specified host and port. The receive( ) method will block execution until a packet is received by the underlying socket, at which time the data will be copied into the packet provided.
The other methods provided are a close( ) method to ask for the underlying socket to be shut down, and a getLocalPort( ) method that will return the local port number associated with the socket. This last method is particularly useful when you let the system pick the port number for you.
DatagramPacket objects represent one packet of data that is sent using the UDP protocol (using a DatagramSocket).
The DatagramPacket class provides two constructors: one for outgoing packets and one for incoming packets. The incoming version takes as arguments a byte array to hold the received data and an int specifying the size of the array. The outgoing version also takes the remote host name (as an InetAddress object) and the port number on that host to send the packet to.
There are four methods in the class allowing the data, datagram length, and addressing (InetAdress and port number) information for the packet to be extracted. The methods are named, respectively, getData( ), getLength( ), getAddress( ), and getPort( ).
The InetAddress class represents a host name and its IP numbers. The class itself also provides the functionality to obtain the IP number for a given host namesimilar to the C gethostbyname( ) function on UNIX and UNIX-like platforms.
There are no explicit constructors for InetAddress objects. Instead, you use the static class method getByName( ), which returns a reference to an InetAddress. Because some hosts might be known by more than one IP address, there also is a method getAllByName( ), which returns an array of InetAddress objects.
Aside from the preceding static methods, there are methods that will return a String representation of the host name that the InetAddress represents (getHostName( )) and an array of the raw bytes of the address (getAddress( )). There also is an equals( ) method for the comparison of address objects. The class also supports a toString( ) method for printing out the host name and IP address textually.
This class provides a method to encode arbitrary text in the x-www-form-urlencoded format. The primary use for this is in encoding arguments in URLs for CGI scripts. Nonprinting or punctuation characters are converted to a two-digit hexadecimal number preceded by a % character. Space characters are converted to a + character.
There is no constructor for this class. All of the functionality is provided by means of a static method.
There is one static class method, encode( ), which takes a String representing the text to encode and returns the translated text as a String.
The subclasses of this class provide the implementation of objects that know how to open communications streams for different URL protocol types. More information on how to write handlers for new protocols can be found in Chapter 31, Extending Java with Content and Protocol Handlers.
The constructor for the URLStreamHandler class cannot be called because it is an abstract class.
Each subclass provides its own implementation of the openConnection( ) method, which opens an input stream to the URL specified as an argument. The method should return an appropriate subclass of the URLConnection class.
Subclasses of the ContentHandler abstract class are responsible for turning a raw data stream for a MIME type into a Java object of the appropriate type. Writing handlers for new content types will be covered in detail in Chapter 31.
Because ContentHandler is an abstract class, ContentHandler objects cannot be instantiated. An object implementing ContentHandlerFactory interface decides what the appropriate subclass is for a given MIME content type.
The important method for ContentHandler objects is the getContent( ) method, which does the actual work of turning data read using a URLConnection into a Java object. This method takes as its argument a reference to a URLConnection that will provide an InputStream at the beginning of the representation of an object.
This abstract class provides a mapping from the raw networking classes to the native TCP/IP networking facilities of the host. This means that the Java application does not need to concern itself with the operating system specifics of creating network connections. The Java runtime loads the proper native code for the implementation, which is accessed by means of a SocketImpl object. Each Socket or ServerSocket then uses the SocketImpl object to access the network.
This scheme also allows for flexibility in different network environments. An application does not need to bother with details such as being behind a firewall, because the runtime takes care of loading the proper socket implementation (such as one that knows how to use the SOCKS proxy TCP/IP service).
Unless you are porting Java to a new platform or adding support for something such as connecting through a firewall, you probably will never see or use SocketImpl.
There is one constructor that takes no arguments.
The methods provided by the SocketImpl class will look very familiar to anyone who has done socket programming under a UNIX variant. All of the methods are protected and may only be used by subclasses of SocketImpl that provide specific socket implementations.
The create( ) method creates a socket with the underlying operating system. It takes one boolean argument that specifies whether the created socket should be a stream (TCP) or datagram (UDP) socket. Two calls, connect( ) and bind( ), cause the socket to be associated with a particular address and port.
For server sockets there is the listen( ) method, which tells the operating system how many connections may be pending on the socket. The accept( ) method waits for an incoming connection request. It takes another SocketImpl object as a parameter, which will represent the new connection once it has been established.
To allow reading and writing from the socket, the class provides the getInputStream( ) and getOutputStream( ) methods, which will return a reference to the corresponding stream. Once communication on a socket is finished, the close( ) method may be used to ask the operating system to close the connection. The remaining methods allow read access to the member variables, as well as a toString( ) method for printing a textual representation of the object.
Each SocketImpl object has four protected members:
Javas exception system allows for flexible error handling. The java.net package defines five new exceptions that are discussed in the following sections. All of these exceptions provide the same functionality as any java.lang.Exception object. Each exception is a subclass of java.io.IOException, so they may be handled with code such as the following fragment:
try { // Code that might cause an exception goes here } catch( java.net.IOException e ) { System.err.println( Error on socket operation:\n + e ); return; }
This code could be put inside a for loopfor example, when trying to create a Socket to connect to a heavily loaded host.
This exception is thrown when a host name cannot be resolved into a machine address. The most probable causes for this are the following:
TIP |
---|
If you are sure that you are using the right host name and are still getting this exception, you might need to fix the name-to-IP number mapping. How to go about this depends on the platform you are using. If you are using DNS, you will need to contact the administrator for the domain. If you are using Suns NIS, you will need to have the system administrator change the entry on the NIS server. Finally, you might need to change the local machines host file, usually named hosts or HOSTS (/etc/hosts on UNIX variants, \WINDOWS\HOSTS on Windows 95). In any case, using the IP number itself to connect to the host should work. |
The URLConnection class uses this exception to signal that a given connection does not support a requested facility such as input or output. If you write your own protocol or content handlers and do not override the default methods for getting input or output stream objects, the inherited method will throw this exception. An application that a user can give an arbitrary URL to should watch for this exception (users being the malicious creatures they are!).
This exception is thrown when there is a problem using a socket. One possible cause is that the local port you are asking for is already in use (that is, another process already has the socket open). Some operating systems might wait for a period of time after a socket has been closed before allowing it to be reopened.
Another cause is that the user cannot bind to that particular port. On most UNIX systems, ports numbered less than 1,024 cannot be used by users other than the root or superuser account. This is a security measure, because most well-known services reside on ports in this range. Normal users are not able to start their own server in place of the system version. While you are developing a service, you might want to run the server on a higher numbered port. Once the service has been developed and debugged, you can move it to the normal port.
This exception also is thrown if you try to use the setSocketImplFactory() method of the Socket or ServerSocket classes when the SocketImplFactory already has been set. Usually the Java runtime will set this to a reasonable value for you, but if you are writing your own socket factory (for example, to provide sockets through a firewall) this exception could get thrown.
This exception is raised by the underlying network support library. It is thrown by a native method of the PlainSocketImpl class when the underlying socket facilities returns a protocol error.
The URL class throws this exception if it is given a syntactically invalid URL. One cause can be that the URL specifies a protocol that the URL class does not support. Another cause is that the URL cannot be parsed. A URL for the HTTP or FILE protocols should have the following general form:
protocol://hostname/path[/path/ /path]/object
Where:
This syntax for a URL depends upon the protocol. The complete URL specification can be found in RFC 1738 (see Chapter 27, Introduction to Java Network Programming, for details on retrieving RFC documents), or check out the World Wide Web Consortiums site at http://www.w3.org/ for the latest version.
In addition to the exceptions in the java.net package, several methods throw exceptions from the java.io package. The most common of these is java.io.IOExceptionwhich, for example, is thrown when there is a problem reading a Web resource by the URL class or if there is a problem creating a Socket.
The java.net package defines three interfaces. These primarily are used behind the scenes by the other networking classes rather than by user classes. Unless you are porting Java to a new platform or are extending it to use a new socket protocol, you probably will have no need to implement these interfaces in a class. They are included here for completeness, and for those people who like to take off the cover and poke around the innards to find out how things work.
This interface defines a method that returns a SocketImpl instance appropriate to the underlying operating system. The socket classes use an object implementing this interface to create the SocketImpl objects they need to use the network.
Classes that implement this interface provide a mapping from protocols such as HTTP or FTP into the corresponding URLStreamHandler subclasses. The URL class uses this factory object to obtain a protocol handler.
The URLStreamHandler class uses this interface to obtain ContentHandler objects for different content types. The interface specifies one method, createContentHandler(), which takes the MIME type for which a handler is desired as a String.
This chapter has been a quick introduction to get you acquainted with the networking facilities that Java provides. Appendix C, The Java Class Library, contains more detailed information on the specific arguments and return types for the various methods. Sun also provides complete API documentation on its Web site at http://www.javasoft.com/JDK-1.0/api/packages.html (a PostScript version for printing is also available).
The next chapter, Network Programming, contains examples that show how to use these classes in more detail. Several classes are developed that show how to use the networking facilities covered here to create your own network applications and applets.