A server base class framework
"Despite the more powerful semantics that are available with RMI,
CORBA, and EJB servers, simple TCP servers remain very popular and
useful. One reason for this is because they require none of the
infrastructure of other servers and they can handle requests from any
type of client, as long as the client has access to some sort of TCP
socket library. The tradeoff here is that the application developer is
responsible for defining and programming the complete protocol for the
data that will be exchanged between client and server." [Scott Oaks,
Java Report, Oct 98, p86]
"Network servers are very easy to write in Java for two reasons:
Java's socket classes, and Java's thread class." [ibid]
In the previous multi-threaded server example, one class had the
responsibility of listening for connect requests and launching an
instance of a second class as the "handler". In this example, a single
class performs both roles. All the requisite infrastructure has been
architected in the abstract base class ServerBaseClass.
The starting point is the startServer() method (lines
10-19). It is intended to be called by the code that creates an
instance of a server class derived from ServerBaseClass.
When that happens, the master ServerSocket listener object
is created (line 14), and the baseClass/derivedClass tandem "embeds
itself" (line 16) and launches its "wrapper" thread (line 18).
The run(void) method (line 28) is the key architectural
element. Each time the server accepts a new connection (line 33), it:
- clones itself (line 34)
- sets up new values for the clone's attributes (lines 35-37)
- wraps the clone in a Thread (line 37)
- and submits the new thread to the thread scheduler (line 39)
This new thread will have its run(void) method (line 28)
called when it is allocated to the CPU by the thread scheduler.
Because its "server" attribute is null, it will not try to
accept new connections and launch new threads. Instead, it will call
(line 42) the run(Socket) method (line 45) (whose
implementation is expected to come from a derived class). This results
in a new "handler" thread being created for each client connection, and
the "master" thread doesn't have to worry about the details of handling
multiple clients.
See the following example for a demonstration of a server that inherits
from this server base class framework.