home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / net / ServerSocket.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  12.2 KB  |  352 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)ServerSocket.java    1.32 98/10/02
  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.32, 10/02/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.      * <p>
  66.      * If there is a security manager, 
  67.      * its <code>checkListen</code> method is called
  68.      * with the <code>port</code> argument
  69.      * as its argument to ensure the operation is allowed. 
  70.      * This could result in a SecurityException.
  71.      *
  72.      * @param      port  the port number, or <code>0</code> to use any
  73.      *                   free port.
  74.      * 
  75.      * @exception  IOException  if an I/O error occurs when opening the socket.
  76.      * @exception  SecurityException
  77.      * if a security manager exists and its <code>checkListen</code> 
  78.      * method doesn't allow the operation.
  79.      * 
  80.      * @see        java.net.SocketImpl
  81.      * @see        java.net.SocketImplFactory#createSocketImpl()
  82.      * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  83.      * @see        SecurityManager#checkListen
  84.      */
  85.     public ServerSocket(int port) throws IOException {
  86.     this(port, 50, null);
  87.     }
  88.  
  89.     /**
  90.      * Creates a server socket and binds it to the specified local port 
  91.      * number. A port number of <code>0</code> creates a socket on any 
  92.      * free port. 
  93.      * <p>
  94.      * The maximum queue length for incoming connection indications (a 
  95.      * request to connect) is set to the <code>backlog</code> parameter. If 
  96.      * a connection indication arrives when the queue is full, the 
  97.      * connection is refused. 
  98.      * <p>
  99.      * If the application has specified a server socket factory, that 
  100.      * factory's <code>createSocketImpl</code> method is called to create 
  101.      * the actual socket implementation. Otherwise a "plain" socket is created.
  102.      * <p>
  103.      * If there is a security manager, 
  104.      * its <code>checkListen</code> method is called
  105.      * with the <code>port</code> argument
  106.      * as its argument to ensure the operation is allowed. 
  107.      * This could result in a SecurityException.
  108.      *
  109.      * @param      port     the specified port, or <code>0</code> to use
  110.      *                      any free port.
  111.      * @param      backlog  the maximum length of the queue.
  112.      * 
  113.      * @exception  IOException  if an I/O error occurs when opening the socket.
  114.      * @exception  SecurityException
  115.      * if a security manager exists and its <code>checkListen</code> 
  116.      * method doesn't allow the operation.
  117.      * 
  118.      * @see        java.net.SocketImpl
  119.      * @see        java.net.SocketImplFactory#createSocketImpl()
  120.      * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  121.      * @see        SecurityManager#checkListen
  122.      */
  123.     public ServerSocket(int port, int backlog) throws IOException {
  124.     this(port, backlog, null);
  125.     }
  126.  
  127.     /** 
  128.      * Create a server with the specified port, listen backlog, and 
  129.      * local IP address to bind to.  The <i>bindAddr</i> argument
  130.      * can be used on a multi-homed host for a ServerSocket that
  131.      * will only accept connect requests to one of its addresses.
  132.      * If <i>bindAddr</i> is null, it will default accepting
  133.      * connections on any/all local addresses.
  134.      * The port must be between 0 and 65535, inclusive.
  135.      * 
  136.      * <P>If there is a security manager, this method 
  137.      * calls its <code>checkListen</code> method
  138.      * with the <code>port</code> argument
  139.      * as its argument to ensure the operation is allowed. 
  140.      * This could result in a SecurityException.
  141.      * 
  142.      * <P>
  143.      * @param port the local TCP port
  144.      * @param backlog the listen backlog
  145.      * @param bindAddr the local InetAddress the server will bind to
  146.      * 
  147.      * @throws  SecurityException
  148.      *        if a security manager exists and its <code>checkListen</code> 
  149.      *        method doesn't allow the operation.
  150.      * 
  151.      * @see SocketConstants
  152.      * @see SocketOption
  153.      * @see SocketImpl
  154.      * @see SecurityManager#checkListen
  155.      * @since   JDK1.1
  156.      */
  157.     public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
  158.         this();
  159.  
  160.     if (port < 0 || port > 0xFFFF)
  161.         throw new IllegalArgumentException(
  162.                "Port value out of range: " + port);
  163.     try {
  164.         SecurityManager security = System.getSecurityManager();
  165.         if (security != null) {
  166.         security.checkListen(port);
  167.         }
  168.  
  169.         impl.create(true); // a stream socket
  170.         if (bindAddr == null)
  171.         bindAddr = InetAddress.anyLocalAddress;    
  172.  
  173.         impl.bind(bindAddr, port);
  174.         impl.listen(backlog);
  175.  
  176.     } catch(SecurityException e) {
  177.         impl.close();
  178.         throw e;
  179.     } catch(IOException e) {
  180.         impl.close();
  181.         throw e;
  182.     }
  183.     }
  184.  
  185.     /**
  186.      * Returns the local address of this server socket.
  187.      *
  188.      * @return  the address to which this socket is connected,
  189.      *          or <code>null</code> if the socket is not yet connected.
  190.      */
  191.     public InetAddress getInetAddress() {
  192.     return impl.getInetAddress();
  193.     }
  194.  
  195.     /**
  196.      * Returns the port on which this socket is listening.
  197.      *
  198.      * @return  the port number to which this socket is listening.
  199.      */
  200.     public int getLocalPort() {
  201.     return impl.getLocalPort();
  202.     }
  203.  
  204.     /**
  205.      * Listens for a connection to be made to this socket and accepts 
  206.      * it. The method blocks until a connection is made. 
  207.      *
  208.      * <p>A new Socket <code>s</code> is created and, if there is a security manager, 
  209.      * the security manager's <code>checkAccept</code> method is called
  210.      * with <code>s.getInetAddress().getHostAddress()</code> and
  211.      * <code>s.getPort()</code>
  212.      * as its arguments to ensure the operation is allowed. 
  213.      * This could result in a SecurityException.
  214.      * 
  215.      * @exception  IOException  if an I/O error occurs when waiting for a
  216.      *               connection.
  217.      * @exception  SecurityException  if a security manager exists and its  
  218.      *             <code>checkListen</code> method doesn't allow the operation.
  219.      * 
  220.      * @see SecurityManager#checkAccept
  221.      */
  222.     public Socket accept() throws IOException {
  223.     Socket s = new Socket();
  224.     implAccept(s);
  225.     return s;
  226.     }
  227.  
  228.     /**
  229.      * Subclasses of ServerSocket use this method to override accept()
  230.      * to return their own subclass of socket.  So a FooServerSocket
  231.      * will typically hand this method an <i>empty</i> FooSocket().  On
  232.      * return from implAccept the FooSocket will be connected to a client.
  233.      *
  234.      * @since   JDK1.1
  235.      */
  236.     protected final void implAccept(Socket s) throws IOException {
  237.     SocketImpl si = new PlainSocketImpl();
  238.     try {
  239.         si.address = new InetAddress();
  240.         si.fd = new FileDescriptor();
  241.         impl.accept(si);
  242.         
  243.         SecurityManager security = System.getSecurityManager();
  244.         if (security != null) {
  245.         security.checkAccept(si.getInetAddress().getHostAddress(),
  246.                      si.getPort());
  247.         }
  248.     } catch (IOException e) {
  249.         si.close();
  250.         throw e;
  251.     } catch (SecurityException e) {
  252.         si.close();
  253.         throw e;
  254.     }
  255.     s.impl.address = si.address;
  256.     s.impl.fd = si.fd;
  257.     s.impl.port = si.port;
  258.     s.impl.localport = si.localport;
  259.     si.fd = null;
  260.     }
  261.  
  262.     /**
  263.      * Closes this socket. 
  264.      *
  265.      * @exception  IOException  if an I/O error occurs when closing the socket.
  266.      */
  267.     public void close() throws IOException {
  268.     impl.close();
  269.     }
  270.  
  271.     /** Enable/disable SO_TIMEOUT with the specified timeout, in
  272.      *  milliseconds.  With this option set to a non-zero timeout,
  273.      *  a call to accept() for this ServerSocket
  274.      *  will block for only this amount of time.  If the timeout expires,
  275.      *  a <B>java.io.InterruptedIOException</B> is raised, though the
  276.      *  ServerSocket is still valid.  The option <B>must</B> be enabled
  277.      *  prior to entering the blocking operation to have effect.  The 
  278.      *  timeout must be > 0.
  279.      *  A timeout of zero is interpreted as an infinite timeout.  
  280.      *
  281.      * @since   JDK1.1
  282.      */
  283.     public synchronized void setSoTimeout(int timeout) throws SocketException {
  284.     impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  285.     }
  286.  
  287.     /** Retrive setting for SO_TIMEOUT.  0 returns implies that the
  288.      *  option is disabled (i.e., timeout of infinity).
  289.      *
  290.      * @since   JDK1.1
  291.      */
  292.     public synchronized int getSoTimeout() throws IOException {
  293.     Object o = impl.getOption(SocketOptions.SO_TIMEOUT);
  294.     /* extra type safety */
  295.     if (o instanceof Integer) {
  296.         return ((Integer) o).intValue();
  297.     } else {
  298.         return 0;
  299.     }
  300.     }
  301.  
  302.     /**
  303.      * Returns the implementation address and implementation port of 
  304.      * this socket as a <code>String</code>.
  305.      *
  306.      * @return  a string representation of this socket.
  307.      */
  308.     public String toString() {
  309.     return "ServerSocket[addr=" + impl.getInetAddress() + 
  310.         ",port=" + impl.getPort() + 
  311.         ",localport=" + impl.getLocalPort()  + "]";
  312.     }
  313.  
  314.     /**
  315.      * The factory for all server sockets.
  316.      */
  317.     private static SocketImplFactory factory;
  318.  
  319.     /**
  320.      * Sets the server socket implementation factory for the 
  321.      * application. The factory can be specified only once. 
  322.      * <p>
  323.      * When an application creates a new server socket, the socket 
  324.      * implementation factory's <code>createSocketImpl</code> method is 
  325.      * called to create the actual socket implementation. 
  326.      * <p>
  327.      * If there is a security manager, this method first calls
  328.      * the security manager's <code>checkSetFactory</code> method 
  329.      * to ensure the operation is allowed. 
  330.      * This could result in a SecurityException.
  331.      *
  332.      * @param      fac   the desired factory.
  333.      * @exception  IOException  if an I/O error occurs when setting the
  334.      *               socket factory.
  335.      * @exception  SocketException  if the factory has already been defined.
  336.      * @exception  SecurityException  if a security manager exists and its  
  337.      *             <code>checkSetFactory</code> method doesn't allow the operation.
  338.      * @see        java.net.SocketImplFactory#createSocketImpl()
  339.      * @see        SecurityManager#checkSetFactory
  340.      */
  341.     public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
  342.     if (factory != null) {
  343.         throw new SocketException("factory already defined");
  344.     }
  345.     SecurityManager security = System.getSecurityManager();
  346.     if (security != null) {
  347.         security.checkSetFactory();
  348.     }
  349.     factory = fac;
  350.     }
  351. }
  352.