1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }