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