public class TcpServer
extends java.lang.Object
implements java.lang.Runnable
a simple socket server able to serve multiple client
connections in parallel. Using this class make sense, if the
service to be provided can be coded as a transformation of data
read from an java.io.InputStream
and then written to a
java.io.OutputStream
. To be able to serve several
clients in parallel, a new service object is needed for every
connection. Therefore the constructor has a
ServiceFactory
as a parameter rather than a service
object.
A typical use of this class involves the following steps:
java.lang.Runnable
.
Its run()
method should read input from an
InputStream
, transform it
and write the result to an OutputStream
.ServiceFactory
to
return instances of the above class.TcpServer
with the factory.serve()
method of the
TcpServer
.
If you stick your ServiceFactory
into a FilterServiceFactory
between steps 2 and 3 and pass the result to the
TcpServer
, you get a pipe filter which can be used in
conjunction with other pipe filters and with DistPipeFilter
to built a distributed pipe on the network.
As soon as clients contact the server, it will call the factory
method to fetch a new service instance. It connects it to the input
and output stream from the client, wraps it up in a
Thread
and starts it. By default 10 such service
threads can be running in parallel. When a thread finishes,
TcpServer
takes care to close the streams.
Constructor and Description |
---|
TcpServer(int port,
ServiceFactory fac)
creates a server to listen on the given port.
|
TcpServer(int port,
ServiceFactory fac,
int slots) |
TcpServer(java.net.ServerSocket s,
ServiceFactory fac,
int slots)
creates a server to listen on the given socket.
|
Modifier and Type | Method and Description |
---|---|
void |
run()
calls
serve() and catches exceptions to write them to the
log. |
void |
serve()
starts the server, waiting for connections and serving up to
n requests in parallel.
|
TcpServer |
setDebug()
given that logging was enabled with
setLogging() , we now switch to really verbose logging. |
TcpServer |
setLogging(java.io.PrintStream log) |
void |
shutdown()
closes the socket on which the server is accepting connections
with the effect, that
serve() immediately returns. |
java.lang.String |
toString() |
public TcpServer(java.net.ServerSocket s, ServiceFactory fac, int slots)
creates a server to listen on the given socket. Connection
request are honoured with whatever service the given ServiceFactory
delivers. Up to slots
services are
run in parallel. If all slots are filled, incoming requests are
put on hold by the underlying tcp machinery.
Important: The services created by fac
should not close the input and output stream passed to
them. If they close one of them, this immediately closes the
socket and thereby the other one too. Both streams are close by
the server itself after the service thread finishes.
public TcpServer(int port, ServiceFactory fac) throws java.io.IOException
creates a server to listen on the given port. Up to 10 connections are serviced in parallel.
java.io.IOException
- if no server socket can be opened for the
given port.public TcpServer(int port, ServiceFactory fac, int slots) throws java.io.IOException
java.io.IOException
public TcpServer setLogging(java.io.PrintStream log)
public TcpServer setDebug()
given that logging was enabled with setLogging()
, we now switch to really verbose logging.
public void run()
calls serve()
and catches exceptions to write them to the
log. This method is only here so that a TcpServer
itself can be put into a Thread
. If the server
activity is anyway the main operation of your program, just call
serve()
.
run
in interface java.lang.Runnable
public void shutdown()
closes the socket on which the server is accepting connections
with the effect, that serve()
immediately returns. Any
currently running service threads are not affected.
public void serve() throws java.io.IOException
starts the server, waiting for connections and serving up to
n requests in parallel. The value n is the
number of slots defined in the constructor. This method only
returns if the current thread's interrupt()
method
is called. Note, however, that services not yet finished are just
left running. They are not forcibly shut down.
java.io.IOException
public java.lang.String toString()
toString
in class java.lang.Object