Note that each class implements the Runnable interface. That
way each object will be in its own thread.
import java.net.*;
import java.io.*;
public class Server implements Runnable
{
// listening flag
public boolean bListening;
// server thread reference
private Thread tListener = null;
public Server()
{
try
{
// create a new server socket
ServerSocket server = new ServerSocket(5555);
// start the listening thread
start()
}
catch (IOException e)
{
System.err.println("Couldn't create server socket: "+e.toString());
}
}
public void start()
{
if (tListener == null)
{
tListener = new Thread(this);
}
tListener.start();
}
// This thread is designed to conform to the 1.2 threading
// mechanism (where stop() is deprecated).
public void run()
{
// set the listening flag
bListening = true;
// Socket that represents the current connection
Socket connection;
// loop while listening
while (bListening)
{
// accept a connection on the server socket and
// pass it to the current connection variable
// This will block until a connection is made.
try
{
connection = server.accept();
// create a new handler for this connection
new Handler(connection);
// we're done...null out the reference
connection = null;
}
catch (IOException e)
{
System.err.println("Error accepting a connection: "+e.toString());
}
}
}
}
import java.net.*;
import java.io.*;
public abstract class Handler implements Runnable
{
// Socket for communication with the client
private Socket connection;
// Buffered readers and writers to communicate
// with the user over the socket
protected BufferedReader in;
protected BufferedWriter out;
// Thread for listening for input on the connection
private Thread tListener;
// Listening flag
public boolean bListening;
// constructor
public Handler(Socket connection)
{
this.connection = connection;
try
{
// get the I/O streams and turn them into readers
in = new BufferedReader(new BufferedInputStream(connection.getInputStream()));
out = new BufferedWriter(new BufferedOutputStream(connection.getOutputStream()));
// start the listening thread
start();
}
catch (IOException e)
{
System.err.println("Unable to get I/O streams off the connection: "+e.toString());
}
}
// Start the listening thread
public void start()
{
if (tListener == null)
{
tListener = new Thread(this);
}
tListener.start();
}
// Get input from the client and pass it off to a processor
public void run()
{
// set the listening flag
bListening = true;
// the current line of input
String strLine;
while (bListening)
{
try
{
// block until a line is received
strLine = in.readLine();
// do something with the line
processLine(strLine);
// null out input just in case the garbage collector
// is aggressive, or we had a really long String
strLine = null;
}
catch (IOException e)
{
System.err.println("Error reading input from client: "+e.toString());
}
}
// done processing? close the socket
try
{
connection.close();
}
catch (IOException e)
{
}
// null out variables so the garbage collector has a chance
in = null;
out = null;
connection = null;
}
// Write a string to the client
public void write(String strLine)
{
try
{
// write the string to the client buffer
out.write(strLine, strLine.length());
// flush the buffer to the client, even if not full
out.flush();
}
catch (IOException e)
{
System.err.println("Error writing to client: "+e.toString());
}
}
// you need to implement this...
public abstract void processLine(String strLine);
}
Server class is the basic model for all future servers that
we will be discussion. In essence:
ServerSocket
It is essential that you understand this code to appreciate what we will change in it--such as variable ports and dynamic class creation. The next version of the server will be generic enough to serve almost any needs.
Feel free to quibble about the efficiency of the code inside the
Server.run() method with the assignment of the socket
connection to a variable. This was written this way for clarity, not to
demonstrate bummed code.
Abstract--this will
get a clean compile, as well as encourage extending this
class to provide real functionality.
As far as creating a Talker goes, this class will changed in a few, key ways.
Most future effort will be spent extending this class to create a
protocol specific handler, but some elements will move up to the next level
of Handler, rather than remain here (such as the while loop
control).
This class, in essence: