1. 程式人生 > >[轉]——如何用Java編寫自己的庫

[轉]——如何用Java編寫自己的庫

EchoServer
// $Id$
import java.io.*;
import java.net.*;
import mylib.*;
public class EchoServer extends Server
{
public EchoServer( int port ) {
// The superclass knows what to do with the port number, we
// don't have to care about it
super( port );
}
// This is called by the Server class when a connection
// comes in. "in" and "out" come from the incoming socket
// connection
public void handleConnection( Socket socket ) {
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
// just copy the input to the output
while (true)
out.write( in.read() );
} catch( IOException ie ) {
System.out.println( ie );
}
}
protected void cleanUp() {
System.out.println( "Cleaning up" );
}
static public void main( String args[] ) throws Exception {
// Grab the port number from the command-line
int port = Integer.parseInt( args[0] );
// Have debugging info sent to standard error stream
Server.setDebugStream( System.err );
// Create the server, and it's up and running
new EchoServer( port );
}
}
mylib.Server
// $Id$
package mylib;
import java.io.*;
import java.net.*;
abstract public class Server implements Runnable
{
// the port we'll be listening on
private int port;
// how many connections we've handled
int numConnections;
// the Reporter that's reporting on this Server
private Reporter reporter;
// set this to true to tell the thread to stop accepting
// connections
private boolean mustQuit = false;
public Server( int port ) {
// remember the port number so the thread can
// listen on it
this.port = port;
// the constructor starts a background thread
new Thread( this ).start();
// and start a reporter
reporter = new Reporter( this );
}
// this is our background thread
public void run() {
ServerSocket ss = null;
try {
// get ready to listen
ss = new ServerSocket( port );
while( !mustQuit ) {
// give out some debugging info
debug( "Listening on "+port );
// wait for an incoming connection
Socket s = ss.accept();
// record that we got another connection
numConnections++;
// more debugging info
debug( "Got connection on "+s );
// process the connection -- this is implemented
// by the subclass
handleConnection( s );
}
} catch( IOException ie ) {
debug( ie.toString() );
}
debug( "Shutting down "+ss );
cleanUp();
}
// the default implementation does nothing
abstract public void handleConnection( Socket s );
// tell the thread to stop accepting connections
public void close() {
mustQuit = true;
reporter.close();
}
// Put any last-minute clean-up stuff in here
protected void cleanUp() {
}
// everything below provides a simple debug system for
// this package
// set this to a print stream if you want debug info
// sent to it; otherwise, leave it null
static private PrintStream debugStream;
// we have two versions of this ...
static public void setDebugStream( PrintStream ps ) {
debugStream = ps;
}
// ... just for convenience
static public void setDebugStream( OutputStream out ) {
debugStream = new PrintStream( out );
}
// send debug info to the print stream, if there is one
static public void debug( String s ) {
if (debugStream != null)
debugStream.println( s );
}
}
mylib.Reporter
// $Id$
package mylib;
class Reporter implements Runnable
{
// the Server we are reporting on
private Server server;
// our background thread
private Thread thread;
// set this to true to tell the thread to stop accepting
// connections
private boolean mustQuit = false;
Reporter( Server server ) {
this.server = server;
// create a background thread
thread = new Thread( this );
thread.start();
}
public void run() {
while (!mustQuit) {
// do the reporting
Server.debug( "server has had "+server.numConnections+" connections" );
// then pause a while
try {
Thread.sleep( 5000 );
} catch( InterruptedException ie ) {}
}
}
// tell the background thread to quit
public void close() {
mustQuit = true;
}
}