View Javadoc

    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.net.DatagramSocket;
    19  import java.net.InetAddress;
    20  import java.net.SocketException;
    21
    22  /****
    23   * The DatagramSocketClient provides the basic operations that are required
    24   * of client objects accessing datagram sockets.  It is meant to be
    25   * subclassed to avoid having to rewrite the same code over and over again
    26   * to open a socket, close a socket, set timeouts, etc.  Of special note
    27   * is the {@link #setDatagramSocketFactory  setDatagramSocketFactory }
    28   * method, which allows you to control the type of DatagramSocket the
    29   * DatagramSocketClient creates for network communications.  This is
    30   * especially useful for adding things like proxy support as well as better
    31   * support for applets.  For
    32   * example, you could create a
    33   * {@link org.apache.commons.net.DatagramSocketFactory}
    34   *  that
    35   * requests browser security capabilities before creating a socket.
    36   * All classes derived from DatagramSocketClient should use the
    37   * {@link #_socketFactory_  _socketFactory_ } member variable to
    38   * create DatagramSocket instances rather than instantiating
    39   * them by directly invoking a constructor.  By honoring this contract
    40   * you guarantee that a user will always be able to provide his own
    41   * Socket implementations by substituting his own SocketFactory.
    42   * <p>
    43   * <p>
    44   * @author Daniel F. Savarese
    45   * @see DatagramSocketFactory
    46   ***/
    47
    48  public abstract class DatagramSocketClient
    49  {
    50      /****
    51       * The default DatagramSocketFactory shared by all DatagramSocketClient
    52       * instances.
    53       ***/
    54      private static final DatagramSocketFactory __DEFAULT_SOCKET_FACTORY =
    55          new DefaultDatagramSocketFactory();
    56
    57      /**** The timeout to use after opening a socket. ***/
    58      protected int _timeout_;
    59
    60      /**** The datagram socket used for the connection. ***/
    61      protected DatagramSocket _socket_;
    62
    63      /****
    64       * A status variable indicating if the client's socket is currently open.
    65       ***/
    66      protected boolean _isOpen_;
    67
    68      /**** The datagram socket's DatagramSocketFactory. ***/
    69      protected DatagramSocketFactory _socketFactory_;
    70
    71      /****
    72       * Default constructor for DatagramSocketClient.  Initializes
    73       * _socket_ to null, _timeout_ to 0, and _isOpen_ to false.
    74       ***/
    75      public DatagramSocketClient()
    76      {
    77          _socket_ = null;
    78          _timeout_ = 0;
    79          _isOpen_ = false;
    80          _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
    81      }
    82
    83
    84      /****
    85       * Opens a DatagramSocket on the local host at the first available port.
    86       * Also sets the timeout on the socket to the default timeout set
    87       * by {@link #setDefaultTimeout  setDefaultTimeout() }.
    88       * <p>
    89       * _isOpen_ is set to true after calling this method and _socket_
    90       * is set to the newly opened socket.
    91       * <p>
    92       * @exception SocketException If the socket could not be opened or the
    93       *   timeout could not be set.
    94       ***/
    95      public void open() throws SocketException
    96      {
    97          _socket_ = _socketFactory_.createDatagramSocket();
    98          _socket_.setSoTimeout(_timeout_);
    99          _isOpen_ = true;
    100     }
    101
    102
    103     /****
    104      * Opens a DatagramSocket on the local host at a specified port.
    105      * Also sets the timeout on the socket to the default timeout set
    106      * by {@link #setDefaultTimeout  setDefaultTimeout() }.
    107      * <p>
    108      * _isOpen_ is set to true after calling this method and _socket_
    109      * is set to the newly opened socket.
    110      * <p>
    111      * @param port The port to use for the socket.
    112      * @exception SocketException If the socket could not be opened or the
    113      *   timeout could not be set.
    114      ***/
    115     public void open(int port) throws SocketException
    116     {
    117         _socket_ = _socketFactory_.createDatagramSocket(port);
    118         _socket_.setSoTimeout(_timeout_);
    119         _isOpen_ = true;
    120     }
    121
    122
    123     /****
    124      * Opens a DatagramSocket at the specified address on the local host
    125      * at a specified port.
    126      * Also sets the timeout on the socket to the default timeout set
    127      * by {@link #setDefaultTimeout  setDefaultTimeout() }.
    128      * <p>
    129      * _isOpen_ is set to true after calling this method and _socket_
    130      * is set to the newly opened socket.
    131      * <p>
    132      * @param port The port to use for the socket.
    133      * @param laddr  The local address to use.
    134      * @exception SocketException If the socket could not be opened or the
    135      *   timeout could not be set.
    136      ***/
    137     public void open(int port, InetAddress laddr) throws SocketException
    138     {
    139         _socket_ = _socketFactory_.createDatagramSocket(port, laddr);
    140         _socket_.setSoTimeout(_timeout_);
    141         _isOpen_ = true;
    142     }
    143
    144
    145
    146     /****
    147      * Closes the DatagramSocket used for the connection.
    148      * You should call this method after you've finished using the class
    149      * instance and also before you call {@link #open open() }
    150      * again.   _isOpen_ is set to false and  _socket_ is set to null.
    151      * If you call this method when the client socket is not open,
    152      * a NullPointerException is thrown.
    153      ***/
    154     public void close()
    155     {
    156         _socket_.close();
    157         _socket_ = null;
    158         _isOpen_ = false;
    159     }
    160
    161
    162     /****
    163      * Returns true if the client has a currently open socket.
    164      * <p>
    165      * @return True if the client has a curerntly open socket, false otherwise.
    166      ***/
    167     public boolean isOpen()
    168     {
    169         return _isOpen_;
    170     }
    171
    172
    173     /****
    174      * Set the default timeout in milliseconds to use when opening a socket.
    175      * After a call to open, the timeout for the socket is set using this value.
    176      * This method should be used prior to a call to {@link #open open()}
    177      * and should not be confused with {@link #setSoTimeout setSoTimeout()}
    178      * which operates on the currently open socket.  _timeout_ contains
    179      * the new timeout value.
    180      * <p>
    181      * @param timeout  The timeout in milliseconds to use for the datagram socket
    182      *                 connection.
    183      ***/
    184     public void setDefaultTimeout(int timeout)
    185     {
    186         _timeout_ = timeout;
    187     }
    188
    189
    190     /****
    191      * Returns the default timeout in milliseconds that is used when
    192      * opening a socket.
    193      * <p>
    194      * @return The default timeout in milliseconds that is used when
    195      *         opening a socket.
    196      ***/
    197     public int getDefaultTimeout()
    198     {
    199         return _timeout_;
    200     }
    201
    202
    203     /****
    204      * Set the timeout in milliseconds of a currently open connection.
    205      * Only call this method after a connection has been opened
    206      * by {@link #open open()}.
    207      * <p>
    208      * @param timeout  The timeout in milliseconds to use for the currently
    209      *                 open datagram socket connection.
    210      ***/
    211     public void setSoTimeout(int timeout) throws SocketException
    212     {
    213         _socket_.setSoTimeout(timeout);
    214     }
    215
    216
    217     /****
    218      * Returns the timeout in milliseconds of the currently opened socket.
    219      * If you call this method when the client socket is not open,
    220      * a NullPointerException is thrown.
    221      * <p>
    222      * @return The timeout in milliseconds of the currently opened socket.
    223      ***/
    224     public int getSoTimeout() throws SocketException
    225     {
    226         return _socket_.getSoTimeout();
    227     }
    228
    229
    230     /****
    231      * Returns the port number of the open socket on the local host used
    232      * for the connection.  If you call this method when the client socket
    233      * is not open, a NullPointerException is thrown.
    234      * <p>
    235      * @return The port number of the open socket on the local host used
    236      *         for the connection.
    237      ***/
    238     public int getLocalPort()
    239     {
    240         return _socket_.getLocalPort();
    241     }
    242
    243
    244     /****
    245      * Returns the local address to which the client's socket is bound.
    246      * If you call this method when the client socket is not open, a
    247      * NullPointerException is thrown.
    248      * <p>
    249      * @return The local address to which the client's socket is bound.
    250      ***/
    251     public InetAddress getLocalAddress()
    252     {
    253         return _socket_.getLocalAddress();
    254     }
    255
    256
    257     /****
    258      * Sets the DatagramSocketFactory used by the DatagramSocketClient
    259      * to open DatagramSockets.  If the factory value is null, then a default
    260      * factory is used (only do this to reset the factory after having
    261      * previously altered it).
    262      * <p>
    263      * @param factory  The new DatagramSocketFactory the DatagramSocketClient
    264      * should use.
    265      ***/
    266     public void setDatagramSocketFactory(DatagramSocketFactory factory)
    267     {
    268         if (factory == null)
    269             _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
    270         else
    271             _socketFactory_ = factory;
    272     }
    273 }