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 }