Save This Page
Home » commons-net-2.0-src » org.apache.commons.net » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.commons.net;
   19   
   20   import java.io.IOException;
   21   import java.io.InputStream;
   22   import java.io.OutputStream;
   23   import java.net.InetAddress;
   24   import java.net.InetSocketAddress;
   25   import java.net.Socket;
   26   import java.net.SocketException;
   27   import java.net.UnknownHostException;
   28   
   29   import javax.net.ServerSocketFactory;
   30   import javax.net.SocketFactory;
   31   
   32   
   33   /**
   34    * The SocketClient provides the basic operations that are required of
   35    * client objects accessing sockets.  It is meant to be
   36    * subclassed to avoid having to rewrite the same code over and over again
   37    * to open a socket, close a socket, set timeouts, etc.  Of special note
   38    * is the {@link #setSocketFactory  setSocketFactory }
   39    * method, which allows you to control the type of Socket the SocketClient
   40    * creates for initiating network connections.  This is especially useful
   41    * for adding SSL or proxy support as well as better support for applets.  For
   42    * example, you could create a
   43    * {@link org.apache.commons.net.SocketFactory} that
   44    * requests browser security capabilities before creating a socket.
   45    * All classes derived from SocketClient should use the
   46    * {@link #_socketFactory_  _socketFactory_ } member variable to
   47    * create Socket and ServerSocket instances rather than instanting
   48    * them by directly invoking a constructor.  By honoring this contract
   49    * you guarantee that a user will always be able to provide his own
   50    * Socket implementations by substituting his own SocketFactory.
   51    * @author Daniel F. Savarese
   52    * @see SocketFactory
   53    */
   54   public abstract class SocketClient
   55   {
   56       /**
   57        * The end of line character sequence used by most IETF protocols.  That
   58        * is a carriage return followed by a newline: "\r\n"
   59        */
   60       public static final String NETASCII_EOL = "\r\n";
   61   
   62       /** The default SocketFactory shared by all SocketClient instances. */
   63       private static final SocketFactory __DEFAULT_SOCKET_FACTORY =
   64               SocketFactory.getDefault();
   65       
   66       private static final ServerSocketFactory __DEFAULT_SERVER_SOCKET_FACTORY = 
   67               ServerSocketFactory.getDefault();
   68   
   69       /** The timeout to use after opening a socket. */
   70       protected int _timeout_;
   71   
   72       /** The socket used for the connection. */
   73       protected Socket _socket_;
   74   
   75       /** The default port the client should connect to. */
   76       protected int _defaultPort_;
   77   
   78       /** The socket's InputStream. */
   79       protected InputStream _input_;
   80   
   81       /** The socket's OutputStream. */
   82       protected OutputStream _output_;
   83   
   84       /** The socket's SocketFactory. */
   85       protected SocketFactory _socketFactory_;
   86       
   87       /** The socket's ServerSocket Factory. */
   88       protected ServerSocketFactory _serverSocketFactory_;
   89       
   90       /** The socket's connect timeout (0 = infinite timeout) */
   91       private static final int DEFAULT_CONNECT_TIMEOUT = 0;
   92       protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
   93   
   94       /**
   95        * Default constructor for SocketClient.  Initializes
   96        * _socket_ to null, _timeout_ to 0, _defaultPort to 0,
   97        * _isConnected_ to false, and _socketFactory_ to a shared instance of
   98        * {@link org.apache.commons.net.DefaultSocketFactory}.
   99        */
  100       public SocketClient()
  101       {
  102           _socket_ = null;
  103           _input_ = null;
  104           _output_ = null;
  105           _timeout_ = 0;
  106           _defaultPort_ = 0;
  107           _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
  108           _serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
  109       }
  110   
  111   
  112       /**
  113        * Because there are so many connect() methods, the _connectAction_()
  114        * method is provided as a means of performing some action immediately
  115        * after establishing a connection, rather than reimplementing all
  116        * of the connect() methods.  The last action performed by every
  117        * connect() method after opening a socket is to call this method.
  118        * <p>
  119        * This method sets the timeout on the just opened socket to the default
  120        * timeout set by {@link #setDefaultTimeout  setDefaultTimeout() },
  121        * sets _input_ and _output_ to the socket's InputStream and OutputStream
  122        * respectively, and sets _isConnected_ to true.
  123        * <p>
  124        * Subclasses overriding this method should start by calling
  125        * <code> super._connectAction_() </code> first to ensure the
  126        * initialization of the aforementioned protected variables.
  127        */
  128       protected void _connectAction_() throws IOException
  129       {
  130           _socket_.setSoTimeout(_timeout_);
  131           _input_ = _socket_.getInputStream();
  132           _output_ = _socket_.getOutputStream();
  133       }
  134   
  135   
  136       /**
  137        * Opens a Socket connected to a remote host at the specified port and
  138        * originating from the current host at a system assigned port.
  139        * Before returning, {@link #_connectAction_  _connectAction_() }
  140        * is called to perform connection initialization actions.
  141        * <p>
  142        * @param host  The remote host.
  143        * @param port  The port to connect to on the remote host.
  144        * @exception SocketException If the socket timeout could not be set.
  145        * @exception IOException If the socket could not be opened.  In most
  146        *  cases you will only want to catch IOException since SocketException is
  147        *  derived from it.
  148        */
  149       public void connect(InetAddress host, int port)
  150       throws SocketException, IOException
  151       {
  152           _socket_ = _socketFactory_.createSocket();
  153           _socket_.connect(new InetSocketAddress(host, port), connectTimeout);
  154   
  155           _connectAction_();
  156       }
  157   
  158       /**
  159        * Opens a Socket connected to a remote host at the specified port and
  160        * originating from the current host at a system assigned port.
  161        * Before returning, {@link #_connectAction_  _connectAction_() }
  162        * is called to perform connection initialization actions.
  163        * <p>
  164        * @param hostname  The name of the remote host.
  165        * @param port  The port to connect to on the remote host.
  166        * @exception SocketException If the socket timeout could not be set.
  167        * @exception IOException If the socket could not be opened.  In most
  168        *  cases you will only want to catch IOException since SocketException is
  169        *  derived from it.
  170        * @exception UnknownHostException If the hostname cannot be resolved.
  171        */
  172       public void connect(String hostname, int port)
  173       throws SocketException, IOException
  174       {
  175           _socket_= _socketFactory_.createSocket();
  176           _socket_.connect(new InetSocketAddress(hostname, port), connectTimeout);
  177           
  178           _connectAction_();
  179       }
  180   
  181   
  182       /**
  183        * Opens a Socket connected to a remote host at the specified port and
  184        * originating from the specified local address and port.
  185        * Before returning, {@link #_connectAction_  _connectAction_() }
  186        * is called to perform connection initialization actions.
  187        * <p>
  188        * @param host  The remote host.
  189        * @param port  The port to connect to on the remote host.
  190        * @param localAddr  The local address to use.
  191        * @param localPort  The local port to use.
  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        */
  197       public void connect(InetAddress host, int port,
  198                           InetAddress localAddr, int localPort)
  199       throws SocketException, IOException
  200       {
  201           _socket_ = _socketFactory_.createSocket();
  202           _socket_.bind(new InetSocketAddress(localAddr, localPort));
  203           _socket_.connect(new InetSocketAddress(host, port), connectTimeout);
  204           
  205           _connectAction_();
  206       }
  207   
  208   
  209       /**
  210        * Opens a Socket connected to a remote host at the specified port and
  211        * originating from the specified local address and port.
  212        * Before returning, {@link #_connectAction_  _connectAction_() }
  213        * is called to perform connection initialization actions.
  214        * <p>
  215        * @param hostname  The name of the remote host.
  216        * @param port  The port to connect to on the remote host.
  217        * @param localAddr  The local address to use.
  218        * @param localPort  The local port to use.
  219        * @exception SocketException If the socket timeout could not be set.
  220        * @exception IOException If the socket could not be opened.  In most
  221        *  cases you will only want to catch IOException since SocketException is
  222        *  derived from it.
  223        * @exception UnknownHostException If the hostname cannot be resolved.
  224        */
  225       public void connect(String hostname, int port,
  226                           InetAddress localAddr, int localPort)
  227       throws SocketException, IOException
  228       {
  229           _socket_ =
  230               _socketFactory_.createSocket(hostname, port, localAddr, localPort);
  231           _connectAction_();
  232       }
  233   
  234   
  235       /**
  236        * Opens a Socket connected to a remote host at the current default port
  237        * and originating from the current host at a system assigned port.
  238        * Before returning, {@link #_connectAction_  _connectAction_() }
  239        * is called to perform connection initialization actions.
  240        * <p>
  241        * @param host  The remote host.
  242        * @exception SocketException If the socket timeout could not be set.
  243        * @exception IOException If the socket could not be opened.  In most
  244        *  cases you will only want to catch IOException since SocketException is
  245        *  derived from it.
  246        */
  247       public void connect(InetAddress host) throws SocketException, IOException
  248       {
  249           connect(host, _defaultPort_);
  250       }
  251   
  252   
  253       /**
  254        * Opens a Socket connected to a remote host at the current default
  255        * port and originating from the current host at a system assigned port.
  256        * Before returning, {@link #_connectAction_  _connectAction_() }
  257        * is called to perform connection initialization actions.
  258        * <p>
  259        * @param hostname  The name of the remote host.
  260        * @exception SocketException If the socket timeout could not be set.
  261        * @exception IOException If the socket could not be opened.  In most
  262        *  cases you will only want to catch IOException since SocketException is
  263        *  derived from it.
  264        * @exception UnknownHostException If the hostname cannot be resolved.
  265        */
  266       public void connect(String hostname) throws SocketException, IOException
  267       {
  268           connect(hostname, _defaultPort_);
  269       }
  270   
  271   
  272       /**
  273        * Disconnects the socket connection.
  274        * You should call this method after you've finished using the class
  275        * instance and also before you call
  276        * {@link #connect connect() }
  277        * again.  _isConnected_ is set to false, _socket_ is set to null,
  278        * _input_ is set to null, and _output_ is set to null.
  279        * <p>
  280        * @exception IOException  If there is an error closing the socket.
  281        */
  282       public void disconnect() throws IOException
  283       {
  284           if (_socket_ != null) _socket_.close();
  285           if (_input_ != null) _input_.close();
  286           if (_output_ != null) _output_.close();
  287           if (_socket_ != null) _socket_ = null;
  288           _input_ = null;
  289           _output_ = null;
  290       }
  291   
  292   
  293       /**
  294        * Returns true if the client is currently connected to a server.
  295        * <p>
  296        * @return True if the client is currently connected to a server,
  297        *         false otherwise.
  298        */
  299       public boolean isConnected()
  300       {
  301           if (_socket_ == null)
  302               return false;
  303           
  304           return _socket_.isConnected();
  305       }
  306   
  307   
  308       /**
  309        * Sets the default port the SocketClient should connect to when a port
  310        * is not specified.  The {@link #_defaultPort_  _defaultPort_ }
  311        * variable stores this value.  If never set, the default port is equal
  312        * to zero.
  313        * <p>
  314        * @param port  The default port to set.
  315        */
  316       public void setDefaultPort(int port)
  317       {
  318           _defaultPort_ = port;
  319       }
  320   
  321       /**
  322        * Returns the current value of the default port (stored in
  323        * {@link #_defaultPort_  _defaultPort_ }).
  324        * <p>
  325        * @return The current value of the default port.
  326        */
  327       public int getDefaultPort()
  328       {
  329           return _defaultPort_;
  330       }
  331   
  332   
  333       /**
  334        * Set the default timeout in milliseconds to use when opening a socket.
  335        * This value is only used previous to a call to
  336        * {@link #connect connect()}
  337        * and should not be confused with {@link #setSoTimeout setSoTimeout()}
  338        * which operates on an the currently opened socket.  _timeout_ contains
  339        * the new timeout value.
  340        * <p>
  341        * @param timeout  The timeout in milliseconds to use for the socket
  342        *                 connection.
  343        */
  344       public void setDefaultTimeout(int timeout)
  345       {
  346           _timeout_ = timeout;
  347       }
  348   
  349   
  350       /**
  351        * Returns the default timeout in milliseconds that is used when
  352        * opening a socket.
  353        * <p>
  354        * @return The default timeout in milliseconds that is used when
  355        *         opening a socket.
  356        */
  357       public int getDefaultTimeout()
  358       {
  359           return _timeout_;
  360       }
  361   
  362   
  363       /**
  364        * Set the timeout in milliseconds of a currently open connection.
  365        * Only call this method after a connection has been opened
  366        * by {@link #connect connect()}.
  367        * <p>
  368        * @param timeout  The timeout in milliseconds to use for the currently
  369        *                 open socket connection.
  370        * @exception SocketException If the operation fails.
  371        */
  372       public void setSoTimeout(int timeout) throws SocketException
  373       {
  374           _socket_.setSoTimeout(timeout);
  375       }
  376       
  377       
  378       /**
  379        * Set the underlying socket send buffer size.
  380        * <p>
  381        * @param size The size of the buffer in bytes.
  382        * @throws SocketException 
  383        * @since 2.0
  384        */
  385       public void setSendBufferSize(int size) throws SocketException {
  386           _socket_.setSendBufferSize(size);
  387       }
  388       
  389       
  390       /**
  391        * Sets the underlying socket receive buffer size.
  392        * <p>
  393        * @param size The size of the buffer in bytes.
  394        * @throws SocketException 
  395        * @since 2.0
  396        */
  397       public void setReceiveBufferSize(int size) throws SocketException  {
  398           _socket_.setReceiveBufferSize(size);
  399       }
  400   
  401   
  402       /**
  403        * Returns the timeout in milliseconds of the currently opened socket.
  404        * <p>
  405        * @return The timeout in milliseconds of the currently opened socket.
  406        * @exception SocketException If the operation fails.
  407        */
  408       public int getSoTimeout() throws SocketException
  409       {
  410           return _socket_.getSoTimeout();
  411       }
  412   
  413       /**
  414        * Enables or disables the Nagle's algorithm (TCP_NODELAY) on the
  415        * currently opened socket.
  416        * <p>
  417        * @param on  True if Nagle's algorithm is to be enabled, false if not.
  418        * @exception SocketException If the operation fails.
  419        */
  420       public void setTcpNoDelay(boolean on) throws SocketException
  421       {
  422           _socket_.setTcpNoDelay(on);
  423       }
  424   
  425   
  426       /**
  427        * Returns true if Nagle's algorithm is enabled on the currently opened
  428        * socket.
  429        * <p>
  430        * @return True if Nagle's algorithm is enabled on the currently opened
  431        *        socket, false otherwise.
  432        * @exception SocketException If the operation fails.
  433        */
  434       public boolean getTcpNoDelay() throws SocketException
  435       {
  436           return _socket_.getTcpNoDelay();
  437       }
  438   
  439   
  440       /**
  441        * Sets the SO_LINGER timeout on the currently opened socket.
  442        * <p>
  443        * @param on  True if linger is to be enabled, false if not.
  444        * @param val The linger timeout (in hundredths of a second?)
  445        * @exception SocketException If the operation fails.
  446        */
  447       public void setSoLinger(boolean on, int val) throws SocketException
  448       {
  449           _socket_.setSoLinger(on, val);
  450       }
  451   
  452   
  453       /**
  454        * Returns the current SO_LINGER timeout of the currently opened socket.
  455        * <p>
  456        * @return The current SO_LINGER timeout.  If SO_LINGER is disabled returns
  457        *         -1.
  458        * @exception SocketException If the operation fails.
  459        */
  460       public int getSoLinger() throws SocketException
  461       {
  462           return _socket_.getSoLinger();
  463       }
  464   
  465   
  466       /**
  467        * Returns the port number of the open socket on the local host used
  468        * for the connection.
  469        * <p>
  470        * @return The port number of the open socket on the local host used
  471        *         for the connection.
  472        */
  473       public int getLocalPort()
  474       {
  475           return _socket_.getLocalPort();
  476       }
  477   
  478   
  479       /**
  480        * Returns the local address to which the client's socket is bound.
  481        * <p>
  482        * @return The local address to which the client's socket is bound.
  483        */
  484       public InetAddress getLocalAddress()
  485       {
  486           return _socket_.getLocalAddress();
  487       }
  488   
  489       /**
  490        * Returns the port number of the remote host to which the client is
  491        * connected.
  492        * <p>
  493        * @return The port number of the remote host to which the client is
  494        *         connected.
  495        */
  496       public int getRemotePort()
  497       {
  498           return _socket_.getPort();
  499       }
  500   
  501   
  502       /**
  503        * @return The remote address to which the client is connected.
  504        */
  505       public InetAddress getRemoteAddress()
  506       {
  507           return _socket_.getInetAddress();
  508       }
  509   
  510   
  511       /**
  512        * Verifies that the remote end of the given socket is connected to the
  513        * the same host that the SocketClient is currently connected to.  This
  514        * is useful for doing a quick security check when a client needs to
  515        * accept a connection from a server, such as an FTP data connection or
  516        * a BSD R command standard error stream.
  517        * <p>
  518        * @return True if the remote hosts are the same, false if not.
  519        */
  520       public boolean verifyRemote(Socket socket)
  521       {
  522           InetAddress host1, host2;
  523   
  524           host1 = socket.getInetAddress();
  525           host2 = getRemoteAddress();
  526   
  527           return host1.equals(host2);
  528       }
  529   
  530   
  531       /**
  532        * Sets the SocketFactory used by the SocketClient to open socket
  533        * connections.  If the factory value is null, then a default
  534        * factory is used (only do this to reset the factory after having
  535        * previously altered it).
  536        * <p>
  537        * @param factory  The new SocketFactory the SocketClient should use.
  538        */
  539       public void setSocketFactory(SocketFactory factory)
  540       {
  541           if (factory == null)
  542               _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
  543           else
  544               _socketFactory_ = factory;
  545       }
  546       
  547       /**
  548        * Sets the ServerSocketFactory used by the SocketClient to open ServerSocket
  549        * connections.  If the factory value is null, then a default
  550        * factory is used (only do this to reset the factory after having
  551        * previously altered it).
  552        * <p>
  553        * @param factory  The new ServerSocketFactory the SocketClient should use.
  554        * @since 2.0
  555        */
  556       public void setServerSocketFactory(ServerSocketFactory factory) {
  557           if (factory == null)
  558               _serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
  559           else
  560               _serverSocketFactory_ = factory;
  561       }
  562       
  563       /**
  564        * Sets the connection timeout in milliseconds, which will be passed to the {@link Socket} object's
  565        * connect() method. 
  566        * @param connectTimeout The connection timeout to use (in ms)
  567        * @since 2.0
  568        */
  569       public void setConnectTimeout(int connectTimeout) {
  570           this.connectTimeout = connectTimeout;
  571       }
  572       
  573       /**
  574        * Get the underlying socket connection timeout.
  575        * @return
  576        * @since 2.0
  577        */
  578       public int getConnectTimeout() {
  579           return connectTimeout;
  580       }
  581       
  582       
  583       
  584   }
  585   
  586   

Save This Page
Home » commons-net-2.0-src » org.apache.commons.net » [javadoc | source]