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

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