Serverpublic class Server extends Object 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
connection on a port, passes input and output streams to a specified Service
object which provides the actual service. It can limit the number of
concurrent connections, and logs activity to a specified stream. |
Fields Summary |
---|
ConnectionManager | connectionManager | Hashtable | services | ThreadGroup | threadGroup | PrintWriter | logStream |
Constructors Summary |
---|
public Server(OutputStream logStream, int maxConnections)This is the Server() constructor. It must be passed a stream
to send log output to (may be null), and the limit on the number of
concurrent connections. It creates and starts a ConnectionManager
thread which enforces this limit on connections.
setLogStream(logStream);
log("Starting server");
threadGroup = new ThreadGroup("Server");
connectionManager = new ConnectionManager(threadGroup, maxConnections);
connectionManager.start();
services = new Hashtable();
|
Methods Summary |
---|
public void | addService(Server$Service service, int port)This method makes the server start providing a new service.
It runs the specified Service object on the specified port.
Integer key = new Integer(port); // the hashtable key
// Check whether a service is already on that port
if (services.get(key) != null)
throw new IllegalArgumentException("Port " + port + " already in use.");
// Create a Listener object to listen for connections on the port
Listener listener = new Listener(threadGroup, port, service);
// Store it in the hashtable
services.put(key, listener);
// Log it
log("Starting service " + service.getClass().getName() +
" on port " + port);
// Start the listener running.
listener.start();
| protected synchronized void | log(java.lang.String s)Write the specified string to the log
if (logStream != null) {
logStream.println("[" + new Date() + "] " + s);
logStream.flush();
}
| protected void | log(java.lang.Object o)Write the specified object to the log log(o.toString());
| public static void | main(java.lang.String[] args)A main() method for running the server as a standalone program.
The command-line arguments to the program should be pairs of servicenames
and port numbers. For each pair, the program will dynamically load the
named Service class, instantiate it, and tell the server to provide that
Service on the specified port. The special -control argument should be
followed by a password and port, and will start special server control
service running on the specified port, protected by the specified
password.
try {
if (args.length < 2) // Check number of arguments
throw new IllegalArgumentException("Must start at least one service");
// Create a Server object that uses standard out as its log and
// has a limit of ten concurrent connections at once.
Server s = new Server(System.out, 10);
// Parse the argument list
int i = 0;
while(i < args.length) {
if (args[i].equals("-control")) { // Handle the -control argument
i++;
String password = args[i++];
int port = Integer.parseInt(args[i++]);
s.addService(new Control(s, password), port); // add control service
}
else {
// Otherwise start a named service on the specified port.
// Dynamically load and instantiate a class that implements Service.
String serviceName = args[i++];
Class serviceClass = Class.forName(serviceName); // dynamic load
Service service = (Service)serviceClass.newInstance(); // instantiate
int port = Integer.parseInt(args[i++]);
s.addService(service, port);
}
}
}
catch (Exception e) { // Display a message if anything goes wrong
System.err.println("Server: " + e);
System.err.println("Usage: java Server [-control <password> <port>] " +
"[<servicename> <port> ... ]");
System.exit(1);
}
| public void | removeService(int port)This method makes the server stop providing a service on a port.
It does not terminate any pending connections to that service, merely
causes the server to stop accepting new connections
Integer key = new Integer(port); // hashtable key
// Look up the Listener object for the port in the hashtable of services
final Listener listener = (Listener) services.get(key);
if (listener == null) return;
// Ask the listener to stop
listener.pleaseStop();
// Remove it from the hashtable
services.remove(key);
// And log it.
log("Stopping service " + listener.service.getClass().getName() +
" on port " + port);
| public void | setLogStream(java.io.OutputStream out)A public method to set the current logging stream. Pass null
to turn logging off
if (out != null) logStream = new PrintWriter(new OutputStreamWriter(out));
else logStream = null;
|
|