home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / Socket.java < prev    next >
Text File  |  1997-05-20  |  15KB  |  439 lines

  1. /*
  2.  * @(#)Socket.java    1.29 97/02/10
  3.  * 
  4.  * Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  * 
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  * 
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  * 
  19.  * CopyrightVersion 1.1_beta
  20.  * 
  21.  */
  22.  
  23. package java.net;
  24.  
  25. import java.io.InputStream;
  26. import java.io.OutputStream;
  27. import java.io.IOException;
  28. import java.io.InterruptedIOException;
  29.  
  30. /**
  31.  * This class implements client sockets (also called just 
  32.  * "sockets"). A socket is an endpoint for communication 
  33.  * between two machines. 
  34.  * <p>
  35.  * The actual work of the socket is performed by an instance of the 
  36.  * <code>SocketImpl</code> class. An application, by changing 
  37.  * the socket factory that creates the socket implementation, 
  38.  * can configure itself to create sockets appropriate to the local 
  39.  * firewall. 
  40.  *
  41.  * @author  unascribed
  42.  * @version 1.29, 02/10/97
  43.  * @see     java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  44.  * @see     java.net.SocketImpl
  45.  * @since   JDK1.0
  46.  */
  47. public  
  48. class Socket {
  49.     /**
  50.      * The implementation of this Socket.
  51.      */
  52.     SocketImpl impl;
  53.  
  54.     /**
  55.      * Creates an unconnected socket, with the
  56.      * system-default type of SocketImpl.
  57.      *
  58.      * @since   JDK1.1
  59.      */
  60.     protected Socket() {
  61.     impl = (factory != null) ? factory.createSocketImpl() : 
  62.         new PlainSocketImpl();
  63.     }
  64.  
  65.     /**
  66.      * Creates an unconnected Socket with a user-specified
  67.      * SocketImpl.
  68.      * <P>
  69.      * The <i>impl</i> parameter is an instance of a <B>SocketImpl</B> 
  70.      * the subclass wishes to use on the Socket. 
  71.      *
  72.      * @since   JDK1.1
  73.      */
  74.     protected Socket(SocketImpl impl) throws SocketException {
  75.     this.impl = impl;
  76.     }
  77.  
  78.     /** 
  79.      * Creates a stream socket and connects it to the specified port 
  80.      * number on the named host. 
  81.      * <p>
  82.      * If the application has specified a server socket factory, that 
  83.      * factory's <code>createSocketImpl</code> method is called to create 
  84.      * the actual socket implementation. Otherwise a "plain" socket is created.
  85.      *
  86.      * @param      host   the host name.
  87.      * @param      port   the port number.
  88.      * @exception  IOException  if an I/O error occurs when creating the socket.
  89.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  90.      * @see        java.net.SocketImpl
  91.      * @see        java.net.SocketImplFactory#createSocketImpl()
  92.      * @since      JDK1.0
  93.      */
  94.     public Socket(String host, int port)
  95.     throws UnknownHostException, IOException
  96.     {
  97.     this(InetAddress.getByName(host), port, null, 0, true);
  98.     }
  99.  
  100.     /** 
  101.      * Creates a stream socket and connects it to the specified port 
  102.      * number at the specified IP address. 
  103.      * <p>
  104.      * If the application has specified a socket factory, that factory's 
  105.      * <code>createSocketImpl</code> method is called to create the 
  106.      * actual socket implementation. Otherwise a "plain" socket is created.
  107.      *
  108.      * @param      address   the IP address.
  109.      * @param      port      the port number.
  110.      * @exception  IOException  if an I/O error occurs when creating the socket.
  111.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  112.      * @see        java.net.SocketImpl
  113.      * @see        java.net.SocketImplFactory#createSocketImpl()
  114.      * @since      JDK1.0
  115.      */
  116.     public Socket(InetAddress address, int port) throws IOException {
  117.     this(address, port, null, 0, true);
  118.     }
  119.  
  120.     /** 
  121.      * Creates a socket and connects it to the specified remote host on
  122.      * the specified remote port. The Socket will also bind() to the local
  123.      * address and port supplied.
  124.      * @param host the name of the remote host
  125.      * @param port the remote port
  126.      * @param localAddr the local address the socket is bound to
  127.      * @param localPort the local port the socket is bound to
  128.      * @since   JDK1.1
  129.      */
  130.     public Socket(String host, int port, InetAddress localAddr, 
  131.           int localPort) throws IOException {
  132.     this(InetAddress.getByName(host), port, localAddr, localPort, true);
  133.     }
  134.  
  135.     /** 
  136.      * Creates a socket and connects it to the specified remote address on
  137.      * the specified remote port. The Socket will also bind() to the local
  138.      * address and port supplied.
  139.      * @param address the remote address
  140.      * @param port the remote port
  141.      * @param localAddr the local address the socket is bound to
  142.      * @param localPort the local port the socket is bound to
  143.      * @since   JDK1.1
  144.      */
  145.     public Socket(InetAddress address, int port, InetAddress localAddr, 
  146.           int localPort) throws IOException {
  147.               this(address, port, localAddr, localPort, true);
  148.     };             
  149.  
  150.     /**
  151.      * Creates a stream socket and connects it to the specified port 
  152.      * number on the named host. 
  153.      * <p>
  154.      * If the stream argument is <code>true</code>, this creates a 
  155.      * stream socket. If the stream argument is <code>false</code>, it 
  156.      * creates a datagram socket. 
  157.      * <p>
  158.      * If the application has specified a server socket factory, that 
  159.      * factory's <code>createSocketImpl</code> method is called to create 
  160.      * the actual socket implementation. Otherwise a "plain" socket is created.
  161.      *
  162.      * @param      host     the host name.
  163.      * @param      port     the port number.
  164.      * @param      stream   a <code>boolean</code> indicating whether this is
  165.      *                      a stream socket or a datagram socket.
  166.      * @exception  IOException  if an I/O error occurs when creating the socket.
  167.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  168.      * @see        java.net.SocketImpl
  169.      * @see        java.net.SocketImplFactory#createSocketImpl()
  170.      * @since      JDK1.0
  171.      * @deprecated Use DatagramSocket instead for UDP transport.
  172.      */
  173.     public Socket(String host, int port, boolean stream) throws IOException {
  174.     this(InetAddress.getByName(host), port, null, 0, stream);
  175.     }
  176.  
  177.     /**
  178.      * Creates a socket and connects it to the specified port number at 
  179.      * the specified IP address. 
  180.      * <p>
  181.      * If the stream argument is <code>true</code>, this creates a 
  182.      * stream socket. If the stream argument is <code>false</code>, it 
  183.      * creates a datagram socket. 
  184.      * <p>
  185.      * If the application has specified a server socket factory, that 
  186.      * factory's <code>createSocketImpl</code> method is called to create 
  187.      * the actual socket implementation. Otherwise a "plain" socket is created.
  188.      *
  189.      * @param      address   the IP address.
  190.      * @param      port      the port number.
  191.      * @param      stream    if <code>true</code>, create a stream socket;
  192.      *                       otherwise, create a datagram socket.
  193.      * @exception  IOException  if an I/O error occurs when creating the socket.
  194.      * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  195.      * @see        java.net.SocketImpl
  196.      * @see        java.net.SocketImplFactory#createSocketImpl()
  197.      * @since      JDK1.0
  198.      * @deprecated Use DatagramSocket instead for UDP transport.
  199.      */
  200.     public Socket(InetAddress host, int port, boolean stream) throws IOException {
  201.     this(host, port, null, 0, stream);
  202.     }
  203.     
  204.     private Socket(InetAddress address, int port, InetAddress localAddr, 
  205.           int localPort, boolean stream) throws IOException {
  206.     this();
  207.  
  208.     if (port < 0 || port > 0xFFFF) {
  209.         throw new IllegalArgumentException("port out range:"+port);
  210.     }
  211.  
  212.     if (localPort < 0 || localPort > 0xFFFF) {
  213.         throw new IllegalArgumentException("port out range:"+localPort);
  214.     }
  215.  
  216.     SecurityManager security = System.getSecurityManager();
  217.     if (security != null) {
  218.         security.checkConnect(address.getHostAddress(), port);
  219.     }
  220.  
  221.     try {
  222.         impl.create(stream); 
  223.         if (localAddr != null || localPort > 0) {
  224.         if (localAddr == null) {
  225.             localAddr = InetAddress.anyLocalAddress;
  226.         }
  227.         impl.bind(localAddr, localPort);
  228.         }
  229.         impl.connect(address, port);
  230.     } catch (SocketException e) {
  231.         impl.close();
  232.         throw e;
  233.     }
  234.     }
  235.  
  236.     /**
  237.      * Returns the address to which the socket is connected.
  238.      *
  239.      * @return  the remote IP address to which this socket is connected.
  240.      * @since   JDK1.0
  241.      */
  242.     public InetAddress getInetAddress() {
  243.     return impl.getInetAddress();
  244.     }
  245.  
  246.     /**
  247.      * Gets the local address to which the socket is bound.
  248.      *
  249.      * @since   JDK1.1
  250.      */
  251.     public InetAddress getLocalAddress() {
  252.     InetAddress in = null;
  253.     try {
  254.         in = (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR);
  255.     } catch (Exception e) {
  256.         in = InetAddress.anyLocalAddress; // "0.0.0.0"
  257.     }
  258.     return in;
  259.     }
  260.  
  261.     /**
  262.      * Returns the remote port to which this socket is connected.
  263.      *
  264.      * @return  the remote port number to which this socket is connected.
  265.      * @since   JDK1.0
  266.      */
  267.     public int getPort() {
  268.     return impl.getPort();
  269.     }
  270.  
  271.     /**
  272.      * Returns the local port to which this socket is bound.
  273.      *
  274.      * @return  the local port number to which this socket is connected.
  275.      * @since   JDK1.0
  276.      */
  277.     public int getLocalPort() {
  278.     return impl.getLocalPort();
  279.     }
  280.  
  281.     /**
  282.      * Returns an input stream for this socket.
  283.      *
  284.      * @return     an input stream for reading bytes from this socket.
  285.      * @exception  IOException  if an I/O error occurs when creating the
  286.      *               input stream.
  287.      * @since      JDK1.0
  288.      */
  289.     public InputStream getInputStream() throws IOException {
  290.     return impl.getInputStream();
  291.     }
  292.  
  293.     /**
  294.      * Returns an output stream for this socket.
  295.      *
  296.      * @return     an output stream for writing bytes to this socket.
  297.      * @exception  IOException  if an I/O error occurs when creating the
  298.      *               output stream.
  299.      * @since      JDK1.0
  300.      */
  301.     public OutputStream getOutputStream() throws IOException {
  302.     return impl.getOutputStream();
  303.     }
  304.  
  305.     /**
  306.      * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
  307.      *
  308.      * @since   JDK1.1
  309.      */
  310.     public void setTcpNoDelay(boolean on) throws SocketException {
  311.     impl.setOption(SocketOptions.TCP_NODELAY, new Boolean(on));
  312.     }
  313.  
  314.     /**
  315.      * Tests if TCP_NODELAY is enabled.
  316.      *
  317.      * @since   JDK1.1
  318.      */
  319.     public boolean getTcpNoDelay() throws SocketException {
  320.     return ((Boolean) impl.getOption(SocketOptions.TCP_NODELAY)).booleanValue();
  321.     }
  322.  
  323.     /**
  324.      * Enable/disable SO_LINGER with the specified linger time.  
  325.      *
  326.      * @since   JDK1.1
  327.      */
  328.     public void setSoLinger(boolean on, int val) throws SocketException {
  329.     if (!on) {
  330.         impl.setOption(SocketOptions.SO_LINGER, new Boolean(on));
  331.     } else {
  332.         impl.setOption(SocketOptions.SO_LINGER, new Integer(val));
  333.     }
  334.     }
  335.  
  336.     /**
  337.      * Returns setting for SO_LINGER. -1 returns implies that the
  338.      * option is disabled.
  339.      *
  340.      * @since   JDK1.1
  341.      */
  342.     public int getSoLinger() throws SocketException {
  343.     Object o = impl.getOption(SocketOptions.SO_LINGER);
  344.     if (o instanceof Integer) {
  345.         return ((Integer) o).intValue();
  346.     } else {
  347.         return -1;
  348.     }
  349.     }
  350.  
  351.     /**
  352.      *  Enable/disable SO_TIMEOUT with the specified timeout, in
  353.      *  milliseconds.  With this option set to a non-zero timeout,
  354.      *  a read() call on the InputStream associated with this Socket
  355.      *  will block for only this amount of time.  If the timeout expires,
  356.      *  a <B>java.io.InterruptedIOException</B> is raised, though the
  357.      *  Socket is still valid. The option <B>must</B> be enabled
  358.      *  prior to entering the blocking operation to have effect. The 
  359.      *  timeout must be > 0.
  360.      *  A timeout of zero is interpreted as an infinite timeout.
  361.      *
  362.      * @since   JDK 1.1
  363.      */
  364.     public synchronized void setSoTimeout(int timeout) throws SocketException {
  365.     impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  366.     }
  367.  
  368.     /**
  369.      * Returns setting for SO_TIMEOUT.  0 returns implies that the
  370.      * option is disabled (i.e., timeout of infinity).
  371.      *
  372.      * @since   JDK1.1
  373.      */
  374.     public synchronized int getSoTimeout() throws SocketException {
  375.     Object o = impl.getOption(SocketOptions.SO_TIMEOUT);
  376.     /* extra type safety */
  377.     if (o instanceof Integer) {
  378.         return ((Integer) o).intValue();
  379.     } else {
  380.         return 0;
  381.     }
  382.     }
  383.  
  384.     /**
  385.      * Closes this socket. 
  386.      *
  387.      * @exception  IOException  if an I/O error occurs when closing this socket.
  388.      * @since      JDK1.0
  389.      */
  390.     public synchronized void close() throws IOException {
  391.     impl.close();
  392.     }
  393.  
  394.     /**
  395.      * Converts this socket to a <code>String</code>.
  396.      *
  397.      * @return  a string representation of this socket.
  398.      * @since   JDK1.0
  399.      */
  400.     public String toString() {
  401.     return "Socket[addr=" + impl.getInetAddress() +
  402.         ",port=" + impl.getPort() + 
  403.         ",localport=" + impl.getLocalPort() + "]";
  404.     }
  405.  
  406.     /**
  407.      * The factory for all client sockets.
  408.      */
  409.     private static SocketImplFactory factory;
  410.  
  411.     /**
  412.      * Sets the client socket implementation factory for the 
  413.      * application. The factory can be specified only once. 
  414.      * <p>
  415.      * When an application creates a new client socket, the socket 
  416.      * implementation factory's <code>createSocketImpl</code> method is 
  417.      * called to create the actual socket implementation. 
  418.      *
  419.      * @param      fac   the desired factory.
  420.      * @exception  IOException  if an I/O error occurs when setting the
  421.      *               socket factory.
  422.      * @exception  SocketException  if the factory is already defined.
  423.      * @see        java.net.SocketImplFactory#createSocketImpl()
  424.      * @since      JDK1.0
  425.      */
  426.     public static synchronized void setSocketImplFactory(SocketImplFactory fac)
  427.     throws IOException
  428.     {
  429.     if (factory != null) {
  430.         throw new SocketException("factory already defined");
  431.     }
  432.     SecurityManager security = System.getSecurityManager();
  433.     if (security != null) {
  434.         security.checkSetFactory();
  435.     }
  436.     factory = fac;
  437.     }
  438. }
  439.