Coverage report

  %line %branch
org.apache.commons.net.SocketClient
52% 
96% 

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

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.