ServerSocket是一个类而不是接口,但是其具体实现由SocketImpl来决定。

ServerSocket提供了5个构造函数,其中public修饰的有四个,其实是调用同一个方法。public构造函数中使用了setImpl来生成SocketImpl,setImpl方法中使用SocketImplFactory来生成SocketImpl。ServerSocket中的factory变量由static修饰,并且可以通过public static synchronized void setSocketFactory方法来指定。

ServerSocket中的factory变量供同一个应用中的所有ServerSocket使用。

 把ServerSocket浏览一遍后,发觉这像是一个代理模式和抽象工厂模式的结合使用。ServerSocketFactory接口只定义了一个默认修饰符的方法:createSocketImpl,它需要返回一个SocketImpl实例。ServerSocket中SocketImpl的默认实现是SocksSocketImpl。

-----------------------------------------------------------

用法:

可以通过ServerSocket构造函数中的backlog来设置连接数。

可以使用自制的ServerSocketFactory,来提供一个继承自SocketImpl的类的实例。

/**
     * Package-private constructor to create a ServerSocket associated with
     * the given SocketImpl.
     */
    ServerSocket(SocketImpl impl) {
        this.impl = impl;
        impl.setServerSocket(this);
    }
 /**
     * Creates an unbound server socket.
     *
     * @exception IOException IO error when opening the socket.
     * @revised 1.4
     */
    public ServerSocket() throws IOException {
        setImpl();
    }
 public ServerSocket(int port) throws IOException {
        this(port, 50, null);
    }
 public ServerSocket(int port, int backlog) throws IOException {
        this(port, backlog, null);
    }
public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
        setImpl();
        if (port < 0 || port > 0xFFFF)
            throw new IllegalArgumentException(
                       "Port value out of range: " + port);
        if (backlog < 1)
          backlog = 50;
        try {
            bind(new InetSocketAddress(bindAddr, port), backlog);
        } catch(SecurityException e) {
            close();
            throw e;
        } catch(IOException e) {
            close();
            throw e;
        }
    }
/**
     * The factory for all server sockets.
     */
    private static SocketImplFactory factory = null;

 

 

/**
 * This class implements server sockets. A server socket waits for
 * requests to come in over the network. It performs some operation
 * based on that request, and then possibly returns a result to the requester.
 * <p>
 * The actual work of the server socket is performed by an instance
 * of the {@code SocketImpl} class. An application can
 * change the socket factory that creates the socket
 * implementation to configure itself to create sockets
 * appropriate to the local firewall.
 *
 * @author  unascribed
 * @see     java.net.SocketImpl
 * @see     java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
 * @see     java.nio.channels.ServerSocketChannel
 * @since   JDK1.0
 */
public
class ServerSocket implements java.io.Closeable {

设置SocketImplFactory

/**
     * Sets the server socket implementation factory for the
     * application. The factory can be specified only once.
     * <p>
     * When an application creates a new server socket, the socket
     * implementation factory's {@code createSocketImpl} method is
     * called to create the actual socket implementation.
     * <p>
     * Passing {@code null} to the method is a no-op unless the factory
     * was already set.
     * <p>
     * If there is a security manager, this method first calls
     * the security manager's {@code checkSetFactory} method
     * to ensure the operation is allowed.
     * This could result in a SecurityException.
     *
     * @param      fac   the desired factory.
     * @exception  IOException  if an I/O error occurs when setting the
     *               socket factory.
     * @exception  SocketException  if the factory has already been defined.
     * @exception  SecurityException  if a security manager exists and its
     *             {@code checkSetFactory} method doesn't allow the operation.
     * @see        java.net.SocketImplFactory#createSocketImpl()
     * @see        SecurityManager#checkSetFactory
     */
    public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {

setImpl

private void setImpl() {
        if (factory != null) {
            impl = factory.createSocketImpl();
            checkOldImpl();
        } else {
            // No need to do a checkOldImpl() here, we know it's an up to date
            // SocketImpl!
            impl = new SocksSocketImpl();
        }
        if (impl != null)
            impl.setServerSocket(this);
    }

 SocketImpl

/**
 * The abstract class {@code SocketImpl} is a common superclass
 * of all classes that actually implement sockets. It is used to
 * create both client and server sockets.
 * <p>
 * A "plain" socket implements these methods exactly as
 * described, without attempting to go through a firewall or proxy.
 *
 * @author  unascribed
 * @since   JDK1.0
 */
public abstract class SocketImpl implements SocketOptions {