Client- Server Programming in Java



Since Java has been designed to be run across networks, the mechanisms for running programs across different machines are much simpler than in other programming languages.  This document will take you briefly  through some of the theory of how to use Java to enable computers to interact.  You should consult texts on Java, in general, or networking in Java in particular, to  get a fuller picture.

The communications systems for Java are based upon the Input/Output structure, in particular Streams.  So we will start the survey there.
 
 

Section 1:  Data in Java

A bit is a binary character.  At the level of the hardware it is a voltage level, either high or low.  High voltage is generally denoted by 1 and low by 0.  All data (including descriptions of actions, and of memory locations) is encoded as sequences of 0's and 1's.

In most computer languages, the basic word length is 8 bits.  An 8-bit word is called a byte.  Since bytes form the basic building blocks of Java, the original IO--which is also the original mechanism for network communications--is based on bytes.  This mechanism is that of a stream.  There has lately been a move towards encoding by  unicode, which uses 16-bit words as the standard unit.  Because of this Java also has a mechanism based on 16-bit words.  This mechanism is called Readers and Writers.  The Reader and Writer class hierarchies are very similar to the Stream ones.  In both cases, the computer level representation is called the binary representation and the human readable version is called the textual version.
 
 

Section 2: Streams

A stream is an abstraction representing flowing bytes.  The class hierarchy is quite deep and complex but all of the flavours of stream have the same basic structure.  The root of  the hierarcy is the abstract class Stream.  Immediately under Sream are the abstract classes InputStream and OutputStream  To give an idea if their use, a n annotated definition of the InputStream class is given below:
 
 

        abstract class InputStream
        {
             int read ( ) throws IOException;

                // this reads a single byte from the input and returns it as an integer (-1 for end of stream)
                // When called, it will block the running program until appropriate data is available for reading

              int read (byte [] buffer) throws IOException;

                //  this reads a collection of bytes from the input, placing them into an array here called buffer
                //  returns an integer that is the number of bytes read (-1 for end of stream)

             long skip (long n) throws IOException;

               //skips n bytes from input and returns the number of byest skipped

             int available( ) throws IOException;

               //determines the number of bytes readable

             void close ( )  IOException;

               //closes the inputStream

        }

Note that the IOExceptions get called when there is a problem with the streamn; e.g. if a connection goes down.

This just reads bytes.  To read higher levels of data abstractions, you can use a DataInputStream.  This supports the following methods that should be pretty self-explanatary:

                          readByte ( );     readBoolean( );     readChar ( );    readDouble ( );    readInt ( );     readLong ( );    readShort ( );
 

The following Table is taken from Eckel: Thinking in Java:
 
Class Function Constructor Arguments How to use it
ByteArray-InputStream Allows a buffer in memory to be used as an InputStream The buffer from which to extract the bytes. As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
StringBuffer-InputStream Converts a String into an InputStream A String. The underlying implementation actually uses a StringBuffer. As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
File-InputStream For reading information from a file A String representing the file name, or a File or FileDescriptor object. As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
Piped-InputStream Produces the data that's being written to the associated PipedOutput-Stream. Implements the piping concept.    
PipedOutputStream As a source of data in multithreading. Connect it to a FilterInputStream object to provide a useful interface.    
Sequence-InputStream Converts two or more InputStream objects into a single InputStream Two InputStream objects or an Enumeration for a container of InputStream objects. As a source of data. Connect it to a FilterInputStream object to provide a useful interface.
Filter-InputStream Abstract class which is an interface for decorators that provide useful functionality to the other InputStream classes.    
       

 
 
 

Section 2: Network Programming