and write data with Java's I/O streams,"
we started to explore the
input/output (I/O) classes, interfaces, and operations provided by the Java
platform. Now, we'll continue our exploration of the I/O facilities provided by
the Java platform by showing how the same techniques, classes, and data types
used for reading and writing data to local file systems can be used when reading
and writing data across remote connections.
A computer is typically endowed with one physical connection through which all data that's destined for it must enter. The problem with this is that many types of data, transported using many different protocols, must use this one physical connection, often at the same time. So does the poor digital device handle this predicament? Using a concept known as ports, the crafty little machine exposes a facade to the outside world that gives the impression that it is actually endowed with a limitless number of physical connections.
A port is simply a number that a computer system uses to route data to the
appropriate application. Some port numbers, called well-known ports, are
reserved for special services such as HTTP, FTP, and SMTP. Well-known port
numbers range from 0 to 1023. The port number, along with information
identifying that destination computer, accompanies data when it is transmitted
across a network connection. This phenomenon opens application communications up
to all kinds of possibilities, including hackers, but we'll leave that
discussion for another time.
Java network applications, broadly speaking,
are concerned with two types of communications, TCP (connection-based) and UDP
(connectionless). In connection-based communications, an application
associates/binds endpoints known as sockets to specific port numbers.
This effectively directs the system to route all data intended for an
application to a specified port. In connectionless communications, individual
packets containing a port number are broadcasted to the intended
All of this techie talk can quickly turn into a lot of
mumbo-jumbo. Fortunately for us, Java has provided the java.net package.
Classes and interfaces within this package provide a unified set of abstractions
for applications to use for network communications.
The java.net package
The java.net package exposed by the Java platform provides a class,
Socket, that represents one connection in a multiconnection conversation
between one Java program and another. The Socket class hides the nasty
details of each particular native system from a Java program. The
java.net.Socket class allows Java programs to communicate over a network
in a platform-agnostic manner. Additionally, the java.net package
provides a class, ServerSocket, that represents a connection that
server-oriented applications use to accept incoming connections from client
The java.net package provides classes and interfaces
for writing programs that use either TCP or UDP. Applications communicating with
TCP use the URL, URLConnection, Socket, and
ServerSocket classes. Applications communicating with UDP use the
DatagramPacket, DatagramSocket, and MulticastSocket
Reading and writing to sockets
Java programs that use the socket classes from the java.net package must
initialize the connections they want to communicate over. Then, data must be
written to and read from the connection. To read and write data to a socket
connection, we obtain an output or input stream from the socket and then read
and write to these streams in a manner similar to the techniques we used to
write to a file located on a local file system.
TCP client and server
Let's look at a simple example that demonstrates this interaction of connections
and data streams. The code is shown in Listing A. The program implements a client class,
TCPClient, that connects to the server class, TCPServer. The
server receives data from the client, writes the data to System.out, and
then sends acknowledgment back to the client.
The server opens a socket on port 7776 and then waits for a client to connect. Once a client has successfully connected, the server will open the input stream and the output stream on the client socket to read and write data. Notice how we use streams and readers in much the same way we do to write to a local file system.
The client (see Listing B) will attempt to create a socket on port 7776
that connects to the server. If the attempt to connect succeeds, the client will
read data entered by the user and then write that data to the server using the
output stream provided by the socket. The client program will read the data
passed back from the server and display it to System.out.
The networking classes provided by the Java platform enable us to implement applications that communicate across a network/remote connection. Using Java's socket classes, we can communicate between two or more clients and/or servers.
In our next article, we'll extend our discussion of Java's networking framework into the realm of the Internet and URLs. We'll also look at how we can use the same data transfer mechanisms to read and write data over URL connections.