home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / net / ServerSocket.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  9.7 KB  |  291 lines

  1. /*
  2.  * @(#)ServerSocket.java    1.30 98/03/18
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.net;
  16.  
  17. import java.io.IOException;
  18. import java.io.FileDescriptor;
  19.  
  20. /**
  21.  * This class implements server sockets. A server socket waits for 
  22.  * requests to come in over the network. It performs some operation 
  23.  * based on that request, and then possibly returns a result to the requester.
  24.  * <p>
  25.  * The actual work of the server socket is performed by an instance 
  26.  * of the <code>SocketImpl</code> class. An application can 
  27.  * change the socket factory that creates the socket 
  28.  * implementation to configure itself to create sockets 
  29.  * appropriate to the local firewall. 
  30.  *
  31.  * @author  unascribed
  32.  * @version 1.30, 03/18/98
  33.  * @see     java.net.SocketImpl
  34.  * @see     java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  35.  * @since   JDK1.0
  36.  */
  37. public 
  38. class ServerSocket {
  39.     /**
  40.      * The implementation of this Socket.
  41.      */
  42.     private SocketImpl impl;
  43.  
  44.     /**
  45.      * Creates an unconnected server socket. Note: this method
  46.      * should not be public.
  47.      * @exception IOException IO error when opening the socket.
  48.      */
  49.     private ServerSocket() throws IOException {
  50.     impl = (factory != null) ? factory.createSocketImpl() : 
  51.         new PlainSocketImpl();
  52.     }
  53.  
  54.     /**
  55.      * Creates a server socket on a specified port. A port of 
  56.      * <code>0</code> creates a socket on any free port. 
  57.      * <p>
  58.      * The maximum queue length for incoming connection indications (a 
  59.      * request to connect) is set to <code>50</code>. If a connection 
  60.      * indication arrives when the queue is full, the connection is refused.
  61.      * <p>
  62.      * If the application has specified a server socket factory, that 
  63.      * factory's <code>createSocketImpl</code> method is called to create 
  64.      * the actual socket implementation. Otherwise a "plain" socket is created.
  65.      *
  66.      * @param      port  the port number, or <code>0</code> to use any
  67.      *                   free port.
  68.      * @exception  IOException  if an I/O error occurs when opening the socket.
  69.      * @see        java.net.SocketImpl
  70.      * @see        java.net.SocketImplFactory#createSocketImpl()
  71.      * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  72.      */
  73.     public ServerSocket(int port) throws IOException {
  74.     this(port, 50, null);
  75.     }
  76.  
  77.     /**
  78.      * Creates a server socket and binds it to the specified local port 
  79.      * number. A port number of <code>0</code> creates a socket on any 
  80.      * free port. 
  81.      * <p>
  82.      * The maximum queue length for incoming connection indications (a 
  83.      * request to connect) is set to the <code>backlog</code> parameter. If 
  84.      * a connection indication arrives when the queue is full, the 
  85.      * connection is refused. 
  86.      * <p>
  87.      * If the application has specified a server socket factory, that 
  88.      * factory's <code>createSocketImpl</code> method is called to create 
  89.      * the actual socket implementation. Otherwise a "plain" socket is created.
  90.      *
  91.      * @param      port     the specified port, or <code>0</code> to use
  92.      *                      any free port.
  93.      * @param      backlog  the maximum length of the queue.
  94.      * @exception  IOException  if an I/O error occurs when opening the socket.
  95.      * @see        java.net.SocketImpl
  96.      * @see        java.net.SocketImplFactory#createSocketImpl()
  97.      * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  98.      */
  99.     public ServerSocket(int port, int backlog) throws IOException {
  100.     this(port, backlog, null);
  101.     }
  102.  
  103.     /** 
  104.      * Create a server with the specified port, listen backlog, and 
  105.      * local IP address to bind to.  The <i>bindAddr</i> argument
  106.      * can be used on a multi-homed host for a ServerSocket that
  107.      * will only accept connect requests to one of its addresses.
  108.      * If <i>bindAddr</i> is null, it will default accepting
  109.      * connections on any/all local addresses.
  110.      * The port must be between 0 and 65535, inclusive.
  111.      * <P>
  112.      * @param port the local TCP port
  113.      * @param backlog the listen backlog
  114.      * @param bindAddr the local InetAddress the server will bind to
  115.      * @see SocketConstants
  116.      * @see SocketOption
  117.      * @see SocketImpl
  118.      * @see   JDK1.1
  119.      */
  120.     public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
  121.         this();
  122.  
  123.     if (port < 0 || port > 0xFFFF)
  124.         throw new IllegalArgumentException(
  125.                "Port value out of range: " + port);
  126.     try {
  127.         SecurityManager security = System.getSecurityManager();
  128.         if (security != null) {
  129.         security.checkListen(port);
  130.         }
  131.  
  132.         impl.create(true); // a stream socket
  133.         if (bindAddr == null)
  134.         bindAddr = InetAddress.anyLocalAddress;    
  135.  
  136.         impl.bind(bindAddr, port);
  137.         impl.listen(backlog);
  138.  
  139.     } catch(SecurityException e) {
  140.         impl.close();
  141.         throw e;
  142.     } catch(IOException e) {
  143.         impl.close();
  144.         throw e;
  145.     }
  146.     }
  147.  
  148.     /**
  149.      * Returns the local address of this server socket.
  150.      *
  151.      * @return  the address to which this socket is connected,
  152.      *          or <code>null</code> if the socket is not yet connected.
  153.      */
  154.     public InetAddress getInetAddress() {
  155.     return impl.getInetAddress();
  156.     }
  157.  
  158.     /**
  159.      * Returns the port on which this socket is listening.
  160.      *
  161.      * @return  the port number to which this socket is listening.
  162.      */
  163.     public int getLocalPort() {
  164.     return impl.getLocalPort();
  165.     }
  166.  
  167.     /**
  168.      * Listens for a connection to be made to this socket and accepts 
  169.      * it. The method blocks until a connection is made. 
  170.      *
  171.      * @exception  IOException  if an I/O error occurs when waiting for a
  172.      *               connection.
  173.      */
  174.     public Socket accept() throws IOException {
  175.     Socket s = new Socket();
  176.     implAccept(s);
  177.     return s;
  178.     }
  179.  
  180.     /**
  181.      * Subclasses of ServerSocket use this method to override accept()
  182.      * to return their own subclass of socket.  So a FooServerSocket
  183.      * will typically hand this method an <i>empty</i> FooSocket().  On
  184.      * return from implAccept the FooSocket will be connected to a client.
  185.      *
  186.      * @since   JDk1.1
  187.      */
  188.     protected final void implAccept(Socket s) throws IOException {
  189.     try {
  190.         //s.impl.create(true);
  191.         s.impl.address = new InetAddress();
  192.         s.impl.fd = new FileDescriptor();
  193.         impl.accept(s.impl);
  194.         
  195.         SecurityManager security = System.getSecurityManager();
  196.         if (security != null) {
  197.         security.checkAccept(s.getInetAddress().getHostAddress(),
  198.                      s.getPort());
  199.         }
  200.     } catch (IOException e) {
  201.         s.close();
  202.         throw e;
  203.     } catch (SecurityException e) {
  204.         s.close();
  205.         throw e;
  206.     }
  207.     }
  208.  
  209.     /**
  210.      * Closes this socket. 
  211.      *
  212.      * @exception  IOException  if an I/O error occurs when closing the socket.
  213.      */
  214.     public void close() throws IOException {
  215.     impl.close();
  216.     }
  217.  
  218.     /** Enable/disable SO_TIMEOUT with the specified timeout, in
  219.      *  milliseconds.  With this option set to a non-zero timeout,
  220.      *  a call to accept() for this ServerSocket
  221.      *  will block for only this amount of time.  If the timeout expires,
  222.      *  a <B>java.io.InterruptedIOException</B> is raised, though the
  223.      *  ServerSocket is still valid.  The option <B>must</B> be enabled
  224.      *  prior to entering the blocking operation to have effect.  The 
  225.      *  timeout must be > 0.
  226.      *  A timeout of zero is interpreted as an infinite timeout.  
  227.      *
  228.      * @since   JDK1.1
  229.      */
  230.     public synchronized void setSoTimeout(int timeout) throws SocketException {
  231.     impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  232.     }
  233.  
  234.     /** Retrive setting for SO_TIMEOUT.  0 returns implies that the
  235.      *  option is disabled (i.e., timeout of infinity).
  236.      *
  237.      * @since   JDK1.1
  238.      */
  239.     public synchronized int getSoTimeout() throws IOException {
  240.     Object o = impl.getOption(SocketOptions.SO_TIMEOUT);
  241.     /* extra type safety */
  242.     if (o instanceof Integer) {
  243.         return ((Integer) o).intValue();
  244.     } else {
  245.         return 0;
  246.     }
  247.     }
  248.  
  249.     /**
  250.      * Returns the implementation address and implementation port of 
  251.      * this socket as a <code>String</code>.
  252.      *
  253.      * @return  a string representation of this socket.
  254.      */
  255.     public String toString() {
  256.     return "ServerSocket[addr=" + impl.getInetAddress() + 
  257.         ",port=" + impl.getPort() + 
  258.         ",localport=" + impl.getLocalPort()  + "]";
  259.     }
  260.  
  261.     /**
  262.      * The factory for all server sockets.
  263.      */
  264.     private static SocketImplFactory factory;
  265.  
  266.     /**
  267.      * Sets the server socket implementation factory for the 
  268.      * application. The factory can be specified only once. 
  269.      * <p>
  270.      * When an application creates a new server socket, the socket 
  271.      * implementation factory's <code>createSocketImpl</code> method is 
  272.      * called to create the actual socket implementation. 
  273.      *
  274.      * @param      fac   the desired factory.
  275.      * @exception  IOException  if an I/O error occurs when setting the
  276.      *               socket factory.
  277.      * @exception  SocketException  if the factory has already been defined.
  278.      * @see        java.net.SocketImplFactory#createSocketImpl()
  279.      */
  280.     public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
  281.     if (factory != null) {
  282.         throw new SocketException("factory already defined");
  283.     }
  284.     SecurityManager security = System.getSecurityManager();
  285.     if (security != null) {
  286.         security.checkSetFactory();
  287.     }
  288.     factory = fac;
  289.     }
  290. }
  291.