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 {