    View Javadoc
    1   package org.apache.commons.net;
    2
    3   /* ====================================================================
    4    * The Apache Software License, Version 1.1
    5    *
    6    * Copyright (c) 2001 The Apache Software Foundation.  All rights
    7    * reserved.
    8    *
    9    * Redistribution and use in source and binary forms, with or without
    10   * modification, are permitted provided that the following conditions
    11   * are met:
    12   *
    13   * 1. Redistributions of source code must retain the above copyright
    14   *    notice, this list of conditions and the following disclaimer.
    15   *
    16   * 2. Redistributions in binary form must reproduce the above copyright
    17   *    notice, this list of conditions and the following disclaimer in
    18   *    the documentation and/or other materials provided with the
    19   *    distribution.
    20   *
    21   * 3. The end-user documentation included with the redistribution,
    22   *    if any, must include the following acknowledgment:
    23   *       "This product includes software developed by the
    24   *        Apache Software Foundation (http://www.apache.org/)."
    25   *    Alternately, this acknowledgment may appear in the software itself,
    26   *    if and wherever such third-party acknowledgments normally appear.
    27   *
    28   * 4. The names "Apache" and "Apache Software Foundation" and
    29   *    "Apache Commons" must not be used to endorse or promote products
    30   *    derived from this software without prior written permission. For
    31   *    written permission, please contact apache@apache.org.
    32   *
    33   * 5. Products derived from this software may not be called "Apache",
    34   *    nor may "Apache" appear in their name, without
    35   *    prior written permission of the Apache Software Foundation.
    36   *
    37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
    41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    48   * SUCH DAMAGE.
    49   * ====================================================================
    50   *
    51   * This software consists of voluntary contributions made by many
    52   * individuals on behalf of the Apache Software Foundation.  For more
    53   * information on the Apache Software Foundation, please see
    54   * <http://www.apache.org/>;.
    55   */
    56
    57  import java.io.IOException;
    58  import java.io.InputStream;
    59  import java.io.OutputStream;
    60  import java.net.InetAddress;
    61  import java.net.Socket;
    62  import java.net.SocketException;
    63
    64  /***
    65   * The SocketClient provides the basic operations that are required of
    66   * client objects accessing sockets.  It is meant to be
    67   * subclassed to avoid having to rewrite the same code over and over again
    68   * to open a socket, close a socket, set timeouts, etc.  Of special note
    69   * is the <a href="#setSocketFactory"> setSocketFactory </a>
    70   * method, which allows you to control the type of Socket the SocketClient
    71   * creates for initiating network connections.  This is especially useful
    72   * for adding SSL or proxy support as well as better support for applets.  For
    73   * example, you could create a
    74   * <a href="org.apache.commons.net.SocketFactory.html"> SocketFactory </a> that
    75   * requests browser security capabilities before creating a socket.
    76   * All classes derived from SocketClient should use the
    77   * <a href="#_socketFactory_"> _socketFactory_ </a> member variable to
    78   * create Socket and ServerSocket instances rather than instanting
    79   * them by directly invoking a constructor.  By honoring this contract
    80   * you guarantee that a user will always be able to provide his own
    81   * Socket implementations by substituting his own SocketFactory.
    82   * @author Daniel F. Savarese
    83   * @see SocketFactory
    84   */
    85  public abstract class SocketClient
    86  {
    87      /***
    88       * The end of line character sequence used by most IETF protocols.  That
    89       * is a carriage return followed by a newline: "\r\n"
    90       */
    91      public static final String NETASCII_EOL = "\r\n";
    92
    93      /*** The default SocketFactory shared by all SocketClient instances. */
    94      private static final SocketFactory __DEFAULT_SOCKET_FACTORY =
    95          new DefaultSocketFactory();
    96
    97      /*** The timeout to use after opening a socket. */
    98      protected int _timeout_;
    99
    100     /*** The socket used for the connection. */
    101     protected Socket _socket_;
    102
    103     /***
    104      * A status variable indicating if the client's socket is currently open.
    105      */
    106     protected boolean _isConnected_;
    107
    108     /*** The default port the client should connect to. */
    109     protected int _defaultPort_;
    110
    111     /*** The socket's InputStream. */
    112     protected InputStream _input_;
    113
    114     /*** The socket's OutputStream. */
    115     protected OutputStream _output_;
    116
    117     /*** The socket's SocketFactory. */
    118     protected SocketFactory _socketFactory_;
    119
    120
    121     /***
    122      * Default constructor for SocketClient.  Initializes
    123      * _socket_ to null, _timeout_ to 0, _defaultPort to 0,
    124      * _isConnected_ to false, and _socketFactory_ to a shared instance of
    125      * <a href="org.apache.commons.net.DefaultSocketFactory.html">DefaultSocketFactory </a>.
    126      */
    127     public SocketClient()
    128     {
    129         _socket_ = null;
    130         _input_ = null;
    131         _output_ = null;
    132         _timeout_ = 0;
    133         _defaultPort_ = 0;
    134         _isConnected_ = false;
    135         _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
    136     }
    137
    138
    139     /***
    140      * Because there are so many connect() methods, the _connectAction_()
    141      * method is provided as a means of performing some action immediately
    142      * after establishing a connection, rather than reimplementing all
    143      * of the connect() methods.  The last action performed by every
    144      * connect() method after opening a socket is to call this method.
    145      * <p>
    146      * This method sets the timeout on the just opened socket to the default
    147      * timeout set by <a href="#setDefaultTimeout"> setDefaultTimeout() </a>,
    148      * sets _input_ and _output_ to the socket's InputStream and OutputStream
    149      * respectively, and sets _isConnected_ to true.
    150      * <p>
    151      * Subclasses overriding this method should start by calling
    152      * <code> super._connectAction_() </code> first to ensure the
    153      * initialization of the aforementioned protected variables.
    154      */
    155     protected void _connectAction_() throws IOException
    156     {
    157         _socket_.setSoTimeout(_timeout_);
    158         _input_ = _socket_.getInputStream();
    159         _output_ = _socket_.getOutputStream();
    160         _isConnected_ = true;
    161     }
    162
    163
    164     /***
    165      * Opens a Socket connected to a remote host at the specified port and
    166      * originating from the current host at a system assigned port.
    167      * Before returning, <a href="#_connectAction_"> _connectAction_() </a>
    168      * is called to perform connection initialization actions.
    169      * <p>
    170      * @param host  The remote host.
    171      * @param port  The port to connect to on the remote host.
    172      * @exception SocketException If the socket timeout could not be set.
    173      * @exception IOException If the socket could not be opened.  In most
    174      *  cases you will only want to catch IOException since SocketException is
    175      *  derived from it.
    176      */
    177     public void connect(InetAddress host, int port)
    178     throws SocketException, IOException
    179     {
    180         _socket_ = _socketFactory_.createSocket(host, port);
    181         _connectAction_();
    182     }
    183
    184     /***
    185      * Opens a Socket connected to a remote host at the specified port and
    186      * originating from the current host at a system assigned port.
    187      * Before returning, <a href="#_connectAction_"> _connectAction_() </a>
    188      * is called to perform connection initialization actions.
    189      * <p>
    190      * @param hostname  The name of the remote host.
    191      * @param port  The port to connect to on the remote host.
    192      * @exception SocketException If the socket timeout could not be set.
    193      * @exception IOException If the socket could not be opened.  In most
    194      *  cases you will only want to catch IOException since SocketException is
    195      *  derived from it.
    196      * @exception UnknownHostException If the hostname cannot be resolved.
    197      */
    198     public void connect(String hostname, int port)
    199     throws SocketException, IOException
    200     {
    201         _socket_ = _socketFactory_.createSocket(hostname, port);
    202         _connectAction_();
    203     }
    204
    205
    206     /***
    207      * Opens a Socket connected to a remote host at the specified port and
    208      * originating from the specified local address and port.
    209      * Before returning, <a href="#_connectAction_"> _connectAction_() </a>
    210      * is called to perform connection initialization actions.
    211      * <p>
    212      * @param host  The remote host.
    213      * @param port  The port to connect to on the remote host.
    214      * @param localAddr  The local address to use.
    215      * @param localPort  The local port to use.
    216      * @exception SocketException If the socket timeout could not be set.
    217      * @exception IOException If the socket could not be opened.  In most
    218      *  cases you will only want to catch IOException since SocketException is
    219      *  derived from it.
    220      */
    221     public void connect(InetAddress host, int port,
    222                         InetAddress localAddr, int localPort)
    223     throws SocketException, IOException
    224     {
    225         _socket_ = _socketFactory_.createSocket(host, port, localAddr, localPort);
    226         _connectAction_();
    227     }
    228
    229
    230     /***
    231      * Opens a Socket connected to a remote host at the specified port and
    232      * originating from the specified local address and port.
    233      * Before returning, <a href="#_connectAction_"> _connectAction_() </a>
    234      * is called to perform connection initialization actions.
    235      * <p>
    236      * @param hostname  The name of the remote host.
    237      * @param port  The port to connect to on the remote host.
    238      * @param localAddr  The local address to use.
    239      * @param localPort  The local port to use.
    240      * @exception SocketException If the socket timeout could not be set.
    241      * @exception IOException If the socket could not be opened.  In most
    242      *  cases you will only want to catch IOException since SocketException is
    243      *  derived from it.
    244      * @exception UnknownHostException If the hostname cannot be resolved.
    245      */
    246     public void connect(String hostname, int port,
    247                         InetAddress localAddr, int localPort)
    248     throws SocketException, IOException
    249     {
    250         _socket_ =
    251             _socketFactory_.createSocket(hostname, port, localAddr, localPort);
    252         _connectAction_();
    253     }
    254
    255
    256     /***
    257      * Opens a Socket connected to a remote host at the current default port
    258      * and originating from the current host at a system assigned port.
    259      * Before returning, <a href="#_connectAction_"> _connectAction_() </a>
    260      * is called to perform connection initialization actions.
    261      * <p>
    262      * @param host  The remote host.
    263      * @exception SocketException If the socket timeout could not be set.
    264      * @exception IOException If the socket could not be opened.  In most
    265      *  cases you will only want to catch IOException since SocketException is
    266      *  derived from it.
    267      */
    268     public void connect(InetAddress host) throws SocketException, IOException
    269     {
    270         connect(host, _defaultPort_);
    271     }
    272
    273
    274     /***
    275      * Opens a Socket connected to a remote host at the current default
    276      * port and originating from the current host at a system assigned port.
    277      * Before returning, <a href="#_connectAction_"> _connectAction_() </a>
    278      * is called to perform connection initialization actions.
    279      * <p>
    280      * @param hostname  The name of the remote host.
    281      * @exception SocketException If the socket timeout could not be set.
    282      * @exception IOException If the socket could not be opened.  In most
    283      *  cases you will only want to catch IOException since SocketException is
    284      *  derived from it.
    285      * @exception UnknownHostException If the hostname cannot be resolved.
    286      */
    287     public void connect(String hostname) throws SocketException, IOException
    288     {
    289         connect(hostname, _defaultPort_);
    290     }
    291
    292
    293     /***
    294      * Disconnects the socket connection.
    295      * You should call this method after you've finished using the class
    296      * instance and also before you call
    297      * <a href="#connect">connect() </a>
    298      * again.  _isConnected_ is set to false, _socket_ is set to null,
    299      * _input_ is set to null, and _output_ is set to null.
    300      * <p>
    301      * @exception IOException  If there is an error closing the socket.
    302      */
    303     public void disconnect() throws IOException
    304     {
    305         _socket_.close();
    306         _input_.close();
    307         _output_.close();
    308         _socket_ = null;
    309         _input_ = null;
    310         _output_ = null;
    311         _isConnected_ = false;
    312     }
    313
    314
    315     /***
    316      * Returns true if the client is currently connected to a server.
    317      * <p>
    318      * @return True if the client is currently connected to a server,
    319      *         false otherwise.
    320      */
    321     public boolean isConnected()
    322     {
    323         return _isConnected_;
    324     }
    325
    326
    327     /***
    328      * Sets the default port the SocketClient should connect to when a port
    329      * is not specified.  The <a href="#_defaultPort_"> _defaultPort_ </a>
    330      * variable stores this value.  If never set, the default port is equal
    331      * to zero.
    332      * <p>
    333      * @param port  The default port to set.
    334      */
    335     public void setDefaultPort(int port)
    336     {
    337         _defaultPort_ = port;
    338     }
    339
    340     /***
    341      * Returns the current value of the default port (stored in
    342      * <a href="#_defaultPort_"> _defaultPort_ </a>).
    343      * <p>
    344      * @return The current value of the default port.
    345      */
    346     public int getDefaultPort()
    347     {
    348         return _defaultPort_;
    349     }
    350
    351
    352     /***
    353      * Set the default timeout in milliseconds to use when opening a socket.
    354      * This value is only used previous to a call to
    355      * <a href="#connect">connect()</a>
    356      * and should not be confused with <a href="#setSoTimeout">setSoTimeout()</a>
    357      * which operates on an the currently opened socket.  _timeout_ contains
    358      * the new timeout value.
    359      * <p>
    360      * @param timeout  The timeout in milliseconds to use for the socket
    361      *                 connection.
    362      */
    363     public void setDefaultTimeout(int timeout)
    364     {
    365         _timeout_ = timeout;
    366     }
    367
    368
    369     /***
    370      * Returns the default timeout in milliseconds that is used when
    371      * opening a socket.
    372      * <p>
    373      * @return The default timeout in milliseconds that is used when
    374      *         opening a socket.
    375      */
    376     public int getDefaultTimeout()
    377     {
    378         return _timeout_;
    379     }
    380
    381
    382     /***
    383      * Set the timeout in milliseconds of a currently open connection.
    384      * Only call this method after a connection has been opened
    385      * by <a href="#connect">connect()</a>.
    386      * <p>
    387      * @param timeout  The timeout in milliseconds to use for the currently
    388      *                 open socket connection.
    389      * @exception SocketException If the operation fails.
    390      */
    391     public void setSoTimeout(int timeout) throws SocketException
    392     {
    393         _socket_.setSoTimeout(timeout);
    394     }
    395
    396
    397     /***
    398      * Returns the timeout in milliseconds of the currently opened socket.
    399      * <p>
    400      * @return The timeout in milliseconds of the currently opened socket.
    401      * @exception SocketException If the operation fails.
    402      */
    403     public int getSoTimeout() throws SocketException
    404     {
    405         return _socket_.getSoTimeout();
    406     }
    407
    408     /***
    409      * Enables or disables the Nagle's algorithm (TCP_NODELAY) on the
    410      * currently opened socket.
    411      * <p>
    412      * @param on  True if Nagle's algorithm is to be enabled, false if not.
    413      * @exception SocketException If the operation fails.
    414      */
    415     public void setTcpNoDelay(boolean on) throws SocketException
    416     {
    417         _socket_.setTcpNoDelay(on);
    418     }
    419
    420
    421     /***
    422      * Returns true if Nagle's algorithm is enabled on the currently opened
    423      * socket.
    424      * <p>
    425      * @return True if Nagle's algorithm is enabled on the currently opened
    426      *        socket, false otherwise.
    427      * @exception SocketException If the operation fails.
    428      */
    429     public boolean getTcpNoDelay() throws SocketException
    430     {
    431         return _socket_.getTcpNoDelay();
    432     }
    433
    434
    435     /***
    436      * Sets the SO_LINGER timeout on the currently opened socket.
    437      * <p>
    438      * @param on  True if linger is to be enabled, false if not.
    439      * @param val The linger timeout (in hundredths of a second?)
    440      * @exception SocketException If the operation fails.
    441      */
    442     public void setSoLinger(boolean on, int val) throws SocketException
    443     {
    444         _socket_.setSoLinger(on, val);
    445     }
    446
    447
    448     /***
    449      * Returns the current SO_LINGER timeout of the currently opened socket.
    450      * <p>
    451      * @return The current SO_LINGER timeout.  If SO_LINGER is disabled returns
    452      *         -1.
    453      * @exception SocketException If the operation fails.
    454      */
    455     public int getSoLinger() throws SocketException
    456     {
    457         return _socket_.getSoLinger();
    458     }
    459
    460
    461     /***
    462      * Returns the port number of the open socket on the local host used
    463      * for the connection.
    464      * <p>
    465      * @return The port number of the open socket on the local host used
    466      *         for the connection.
    467      */
    468     public int getLocalPort()
    469     {
    470         return _socket_.getLocalPort();
    471     }
    472
    473
    474     /***
    475      * Returns the local address to which the client's socket is bound.
    476      * <p>
    477      * @return The local address to which the client's socket is bound.
    478      */
    479     public InetAddress getLocalAddress()
    480     {
    481         return _socket_.getLocalAddress();
    482     }
    483
    484     /***
    485      * Returns the port number of the remote host to which the client is
    486      * connected.
    487      * <p>
    488      * @return The port number of the remote host to which the client is
    489      *         connected.
    490      */
    491     public int getRemotePort()
    492     {
    493         return _socket_.getPort();
    494     }
    495
    496
    497     /***
    498      * @return The remote address to which the client is connected.
    499      */
    500     public InetAddress getRemoteAddress()
    501     {
    502         return _socket_.getInetAddress();
    503     }
    504
    505
    506     /***
    507      * Verifies that the remote end of the given socket is connected to the
    508      * the same host that the SocketClient is currently connected to.  This
    509      * is useful for doing a quick security check when a client needs to
    510      * accept a connection from a server, such as an FTP data connection or
    511      * a BSD R command standard error stream.
    512      * <p>
    513      * @return True if the remote hosts are the same, false if not.
    514      */
    515     public boolean verifyRemote(Socket socket)
    516     {
    517         InetAddress host1, host2;
    518
    519         host1 = socket.getInetAddress();
    520         host2 = getRemoteAddress();
    521
    522         return host1.equals(host2);
    523     }
    524
    525
    526     /***
    527      * Sets the SocketFactory used by the SocketClient to open socket
    528      * connections.  If the factory value is null, then a default
    529      * factory is used (only do this to reset the factory after having
    530      * previously altered it).
    531      * <p>
    532      * @param factory  The new SocketFactory the SocketClient should use.
    533      */
    534     public void setSocketFactory(SocketFactory factory)
    535     {
    536         if (factory == null)
    537             _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
    538         else
    539             _socketFactory_ = factory;
    540     }
    541 }
    542
    543

This page was automatically generated by Maven