org.sapia.ubik.net.mplex
Class MultiplexServerSocket

java.lang.Object
  extended by java.net.ServerSocket
      extended by org.sapia.ubik.net.mplex.MultiplexServerSocket
All Implemented Interfaces:
java.lang.Runnable

public class MultiplexServerSocket
extends java.net.ServerSocket
implements java.lang.Runnable

This class is the main server socket that multiplexes the traditionnal java.net.ServerSocket. That means that it listens on the port of the server socket and it provides a mechanism to register different handlers for these new incoming socket connections. These handlers are called socket connectors and they can be used to process multiple types of data streams over the same socket.

For instance, using this MultiplexServerSocket you could handle serialized Java objects and HTTP requests using two different connectors (two distinct handling logic), same host/port. This is achieved through a read-ahead on the incoming stream of data from a new client socket connection. When a new incoming connection is requested by a client, all the registered StreamSelectors are used to determine which socket connector will handle the new connection.

The internals of this MultiplexServerSocket are simple. An instance of this class works on an asynchronous process were new socket connections are first accepted, and then selected. These two steps are described as follows:

  1. acceptor: This first step involves the low-level logic of virtual machine that resides under the Java I/O package. When a client connects to the server, a new MultiplexSocket is created on the server-side; the acceptor adds that new connection/socket to the internal pending queue.
  2. selector: The selector listens on the queue of accepted connections and performs the logic of going through all the candidate socket connectors to determine which one of them handles the new socket connection; if none of the registered connectors is.
To perform this process, the MultiplexServerSocket contains two distinct pools of threads that are configurable using the setAcceptorDaemonThread(int) and setSelectorDaemonThread(int) methods.

The primary goal of the MultiplexServerSocket was to keep the "standard" (non-NIO) programming model of the JDK regarding socket handling. Whether you use this server socket directly or you use a socket connector, the logic is still the same for the client that receives new incoming connections: it calls an accept() method that blocks until a new connection is made. For integration with actual running systems, an adapter is available to make a socket connector look like a server socket. We used that strategy with the open-source Simple HTTP server and it worked transparently and fluidly.

Author:
Jean-Cedric Desrochers
Copyright:
Copyright © 2002-2004 Sapia Open Source Software. All Rights Reserved.
License:
Read the license.txt file of the jar or visit the license page at the Sapia OSS web site
See Also:
MultiplexSocket, MultiplexSocketConnector, ServerSocketAdapter, StreamSelector

Nested Class Summary
 class MultiplexServerSocket.SelectorTask
          This class is responsible of the selection logic of the multiplex.
 
Field Summary
static short DEFAULT_ACCEPTOR_DAEMON_THREAD
          The default number of acceptor daemon thread used to accept connections.
static short DEFAULT_READ_AHEAD_BUFFER_SIZE
          The default number of bytes read ahead fom incoming socket connections.
static short DEFAULT_SELECTOR_DAEMON_THREAD
          The default number of selector daemon thread used to accept connections.
 
Constructor Summary
MultiplexServerSocket()
          Creates a new MultiplexServerSocket instance.
MultiplexServerSocket(int port)
          Creates a new MultiplexServerSocket instance.
MultiplexServerSocket(int port, int backlog)
          Creates a new MultiplexServerSocket instance.
MultiplexServerSocket(int port, int backlog, java.net.InetAddress bindAddr)
          Creates a new MultiplexServerSocket instance.
 
Method Summary
 java.net.Socket accept()
          Listens for a connection to be made to this socket and accepts it.
 void close()
          Closes this multiplex server socket.
 MultiplexSocketConnector createSocketConnector(StreamSelector aSelector)
          This factory method creates a socket connector through which a client will be able to receive incoming socket connections.
 int getAcceptorDaemonThread()
          Returns the number of daemon threads used to accept incoming connections.
 int getReadAheadBufferSize()
          Returns the size of the buffer used to pre-read the incoming bytes of the accepted connection.
 int getSelectorDaemonThread()
          Returns the number of daemon threads used to select an connector for incoming connections.
 void removeSocketConnector(MultiplexSocketConnector aConnector)
          Removes the socket connector passed in from the list of available connectors associated with this server socket.
 void run()
          Implements the Runnable interface and it performs the asynchronous acceptor logic of the multiplex.
 void setAcceptorDaemonThread(int maxThread)
          Changes the number of daemon threads used to accept incoming connections.
 void setReadAheadBufferSize(int aSize)
          Changes the size of the read ahead buffer size.
 void setSelectorDaemonThread(int maxThread)
          Changes the number of daemon threads used to select connectors for incoming connections.
 java.lang.String toString()
          Returns the implementation address and implementation port of this socket as a String.
 
Methods inherited from class java.net.ServerSocket
bind, bind, getChannel, getInetAddress, getLocalPort, getLocalSocketAddress, getReceiveBufferSize, getReuseAddress, getSoTimeout, implAccept, isBound, isClosed, setPerformancePreferences, setReceiveBufferSize, setReuseAddress, setSocketFactory, setSoTimeout
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_READ_AHEAD_BUFFER_SIZE

public static final short DEFAULT_READ_AHEAD_BUFFER_SIZE
The default number of bytes read ahead fom incoming socket connections.

See Also:
Constant Field Values

DEFAULT_ACCEPTOR_DAEMON_THREAD

public static final short DEFAULT_ACCEPTOR_DAEMON_THREAD
The default number of acceptor daemon thread used to accept connections.

See Also:
Constant Field Values

DEFAULT_SELECTOR_DAEMON_THREAD

public static final short DEFAULT_SELECTOR_DAEMON_THREAD
The default number of selector daemon thread used to accept connections.

See Also:
Constant Field Values
Constructor Detail

MultiplexServerSocket

public MultiplexServerSocket()
                      throws java.io.IOException
Creates a new MultiplexServerSocket instance. The server socket is unbound

Throws:
java.io.IOException - If an error occurs opening the socket.

MultiplexServerSocket

public MultiplexServerSocket(int port)
                      throws java.io.IOException
Creates a new MultiplexServerSocket instance. The new server will be bound on the speficied port, or to a free port if the value passed in is 0 (zero). The maximum queue length for incoming connection indications (a request to connect) is set to 50. If a connection indication arrives when the queue is full, the connection is refused.

Parameters:
port - The port number to bind the server or 0 to use any port.
Throws:
java.io.IOException - If an error occurs when opening the socket.

MultiplexServerSocket

public MultiplexServerSocket(int port,
                             int backlog)
                      throws java.io.IOException
Creates a new MultiplexServerSocket instance. The new server will be bound on the speficied port, or to a free port if the value passed in is 0 (zero). The maximum queue length for incoming connection indications (a request to connect) is set to the backlog parameter. If a connection indication arrives when the queue is full, the connection is refused.

Parameters:
port - The port number to bind the server or 0 oi use any port.
backlog - The maximum length of the queue.
Throws:
java.io.IOException - If an error occurs when opening the socket.

MultiplexServerSocket

public MultiplexServerSocket(int port,
                             int backlog,
                             java.net.InetAddress bindAddr)
                      throws java.io.IOException
Creates a new MultiplexServerSocket instance. The new server will be bound on the speficied port, or to a free port if the value passed in is 0 (zero). The server will use the local IP address represented by the bindAddr passed in. The maximum queue length for incoming connection indications (a request to connect) is set to the backlog parameter. If a connection indication arrives when the queue is full, the connection is refused.

Parameters:
port - The port number to bind the server or 0 oi use any port.
backlog - The maximum length of the queue.
bindAddr - The local TCP address the server will bind to. If null the server will accept connections on any/all local addresses.
Throws:
java.io.IOException - If an error occurs when opening the socket.
Method Detail

getReadAheadBufferSize

public int getReadAheadBufferSize()
Returns the size of the buffer used to pre-read the incoming bytes of the accepted connection.

Returns:
The size of the read ahead buffer size.

setReadAheadBufferSize

public void setReadAheadBufferSize(int aSize)
Changes the size of the read ahead buffer size. This method can only be called before starting the server (ie. the initial call to the method accept().

Parameters:
aSize - The new size.
Throws:
java.lang.IllegalStateException - If the server is already running.

getAcceptorDaemonThread

public int getAcceptorDaemonThread()
Returns the number of daemon threads used to accept incoming connections.

Returns:
The number of daemon threads used to accept incoming connections.

getSelectorDaemonThread

public int getSelectorDaemonThread()
Returns the number of daemon threads used to select an connector for incoming connections.

Returns:
The number of daemon threads used to select an connector for incoming connections.

setAcceptorDaemonThread

public void setAcceptorDaemonThread(int maxThread)
Changes the number of daemon threads used to accept incoming connections.

Parameters:
maxThread - The new numbe of running daemon.
Throws:
java.lang.IllegalStateException - If the server is already running.

setSelectorDaemonThread

public void setSelectorDaemonThread(int maxThread)
Changes the number of daemon threads used to select connectors for incoming connections.

Parameters:
maxThread - The new numbe of running daemon.
Throws:
java.lang.IllegalStateException - If the server is already running.

createSocketConnector

public MultiplexSocketConnector createSocketConnector(StreamSelector aSelector)
This factory method creates a socket connector through which a client will be able to receive incoming socket connections. The stream selector passed in will be used y this multiplex server socket to determine if an incoming socket connection must be handled by the created socket connector.

Parameters:
aSelector - The stream selector to assign to the created socket connector.
Returns:
The created socket connector.
Throws:
java.lang.IllegalStateException - If this server socket is closed.

removeSocketConnector

public void removeSocketConnector(MultiplexSocketConnector aConnector)
Removes the socket connector passed in from the list of available connectors associated with this server socket. After this method the multiplex server socket will no longer send new incoming socket connection to the socket connector.

Parameters:
aConnector - The socket connector to remove from this server socket.

accept

public java.net.Socket accept()
                       throws java.io.IOException
Listens for a connection to be made to this socket and accepts it. The default connector of this server socket will be used to act as the main port of entry for clients directly using the server socket instead of the default socket connector. The method blocks until a connection is made.

Overrides:
accept in class java.net.ServerSocket
Returns:
The new Socket
Throws:
java.io.IOException - If an I/O error occurs when waiting for a connection.
java.net.SocketTimeoutException - if a timeout was previously set with setSoTimeout and the timeout has been reached.

close

public void close()
           throws java.io.IOException
Closes this multiplex server socket. If socket connectors are associated to this server scket then they are closed as well.

Overrides:
close in class java.net.ServerSocket
Throws:
java.io.IOException - If an I/O error occurs when closing the socket.

toString

public java.lang.String toString()
Returns the implementation address and implementation port of this socket as a String.

Overrides:
toString in class java.net.ServerSocket
Returns:
A string representation of this socket.

run

public void run()
Implements the Runnable interface and it performs the asynchronous acceptor logic of the multiplex. Used by the acceptor threads, it listens on the underlying server socket and dispacthes all the incoming socket connections to the queue of accepted socket connection. The client socket connections put in that queue are then processed asynchronously by the selector threads.

Specified by:
run in interface java.lang.Runnable


Copyright © 2010 Sapia OSS. All Rights Reserved.