View Javadoc

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