Java Reference
In-Depth Information
its actions to a specified stream and limits the number of concurrent connections
to a specified maximum.
The
Server
class uses a number of inner classes. The
Server.Listener
class is a
thread that waits for connections on a given port. There is one
Listener
object for
each service the
Server
is providing. The
Server.ConnectionManager
class man-
ages the list of current connections to all services. There is one
ConnectionManager
shared by all services. When a
Listener
gets a connection from a client, it passes
it to the
ConnectionManager
, which rejects it if the connection limit has been
reached. If the
ConnectionManager
doesn't reject a client, it creates a
Server.Con-
nection
object to handle the connection.
Connection
is a
Thread
subclass, so each
service can handle multiple connections at a time, making this a multithreaded
server. Each
Connection
object is passed a
Service
object and invokes its
serve()
method, which is what actually provides the service.
The
Service
interface is a nested member of the
Server
class;
Server
includes a
number of implementations of this interface. Many of these implementations are
trivial, demonstration services. The
Control
class, however, is a nontrivial
Service
.
This service provides password-protected runtime access to the server, allowing a
remote administrator to add and remove services, check the server status, and
change the current connection limit.
Finally, the
main()
method of
Server
is a standalone program that creates and
runs a
Server
. By specifying the
-control
argument on the command line, you
can tell this program to create an instance of the
Control
service so that the server
can be administered at runtime. Other arguments to this program specify the
names of
Service
classes to be run and the ports that they should use. For exam-
ple, you could start the server with a command like this:
% java com.davidflanagan.examples.net.Server -control secret 3000 \
com.davidflanagan.examples.net.Server\$Time 3001 \
com.davidflanagan.examples.net.Server\$Reverse 3002
This command starts the
Control
service on port 3000 with the password “secret”,
the
Server.Time
service on port 3001, and the
Server.Reverse
service on port
3002. Once you have started the server program, you can use
GenericClient
(see
Example 5-8) to connect to each of the services it provides. Using the
Control
ser-
vice is the most interesting, of course, and you can use it to add (and remove)
other services.
The best way to understand the
Server
class and its inner classes and interfaces is
to dive in and study the code. It is heavily commented. I recommend that you
skim it, reading comments first, and then go back through and study each class in
detail.
Example 5•9: Server.java
package com.davidflanagan.examples.net;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* This class is a generic framework for a flexible, multi-threaded server.
* It listens on any number of specified ports, and, when it receives a