%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.net.SocketClient |
|
|
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.io.IOException; |
|
19 | import java.io.InputStream; |
|
20 | import java.io.OutputStream; |
|
21 | import java.net.InetAddress; |
|
22 | import java.net.Socket; |
|
23 | import java.net.SocketException; |
|
24 | ||
25 | /** |
|
26 | * The SocketClient provides the basic operations that are required of |
|
27 | * client objects accessing sockets. It is meant to be |
|
28 | * subclassed to avoid having to rewrite the same code over and over again |
|
29 | * to open a socket, close a socket, set timeouts, etc. Of special note |
|
30 | * is the {@link #setSocketFactory setSocketFactory } |
|
31 | * method, which allows you to control the type of Socket the SocketClient |
|
32 | * creates for initiating network connections. This is especially useful |
|
33 | * for adding SSL or proxy support as well as better support for applets. For |
|
34 | * example, you could create a |
|
35 | * {@link org.apache.commons.net.SocketFactory} that |
|
36 | * requests browser security capabilities before creating a socket. |
|
37 | * All classes derived from SocketClient should use the |
|
38 | * {@link #_socketFactory_ _socketFactory_ } member variable to |
|
39 | * create Socket and ServerSocket instances rather than instanting |
|
40 | * them by directly invoking a constructor. By honoring this contract |
|
41 | * you guarantee that a user will always be able to provide his own |
|
42 | * Socket implementations by substituting his own SocketFactory. |
|
43 | * @author Daniel F. Savarese |
|
44 | * @see SocketFactory |
|
45 | */ |
|
46 | public abstract class SocketClient |
|
47 | { |
|
48 | /** |
|
49 | * The end of line character sequence used by most IETF protocols. That |
|
50 | * is a carriage return followed by a newline: "\r\n" |
|
51 | */ |
|
52 | public static final String NETASCII_EOL = "\r\n"; |
|
53 | ||
54 | /** The default SocketFactory shared by all SocketClient instances. */ |
|
55 | 2 | private static final SocketFactory __DEFAULT_SOCKET_FACTORY = |
56 | new DefaultSocketFactory(); |
|
57 | ||
58 | /** The timeout to use after opening a socket. */ |
|
59 | protected int _timeout_; |
|
60 | ||
61 | /** The socket used for the connection. */ |
|
62 | protected Socket _socket_; |
|
63 | ||
64 | /** |
|
65 | * A status variable indicating if the client's socket is currently open. |
|
66 | */ |
|
67 | protected boolean _isConnected_; |
|
68 | ||
69 | /** The default port the client should connect to. */ |
|
70 | protected int _defaultPort_; |
|
71 | ||
72 | /** The socket's InputStream. */ |
|
73 | protected InputStream _input_; |
|
74 | ||
75 | /** The socket's OutputStream. */ |
|
76 | protected OutputStream _output_; |
|
77 | ||
78 | /** The socket's SocketFactory. */ |
|
79 | protected SocketFactory _socketFactory_; |
|
80 | ||
81 | ||
82 | /** |
|
83 | * Default constructor for SocketClient. Initializes |
|
84 | * _socket_ to null, _timeout_ to 0, _defaultPort to 0, |
|
85 | * _isConnected_ to false, and _socketFactory_ to a shared instance of |
|
86 | * {@link org.apache.commons.net.DefaultSocketFactory}. |
|
87 | */ |
|
88 | public SocketClient() |
|
89 | 33 | { |
90 | 33 | _socket_ = null; |
91 | 33 | _input_ = null; |
92 | 33 | _output_ = null; |
93 | 33 | _timeout_ = 0; |
94 | 33 | _defaultPort_ = 0; |
95 | 33 | _isConnected_ = false; |
96 | 33 | _socketFactory_ = __DEFAULT_SOCKET_FACTORY; |
97 | 33 | } |
98 | ||
99 | ||
100 | /** |
|
101 | * Because there are so many connect() methods, the _connectAction_() |
|
102 | * method is provided as a means of performing some action immediately |
|
103 | * after establishing a connection, rather than reimplementing all |
|
104 | * of the connect() methods. The last action performed by every |
|
105 | * connect() method after opening a socket is to call this method. |
|
106 | * <p> |
|
107 | * This method sets the timeout on the just opened socket to the default |
|
108 | * timeout set by {@link #setDefaultTimeout setDefaultTimeout() }, |
|
109 | * sets _input_ and _output_ to the socket's InputStream and OutputStream |
|
110 | * respectively, and sets _isConnected_ to true. |
|
111 | * <p> |
|
112 | * Subclasses overriding this method should start by calling |
|
113 | * <code> super._connectAction_() </code> first to ensure the |
|
114 | * initialization of the aforementioned protected variables. |
|
115 | */ |
|
116 | protected void _connectAction_() throws IOException |
|
117 | { |
|
118 | 34 | _socket_.setSoTimeout(_timeout_); |
119 | 34 | _input_ = _socket_.getInputStream(); |
120 | 34 | _output_ = _socket_.getOutputStream(); |
121 | 34 | _isConnected_ = true; |
122 | 34 | } |
123 | ||
124 | ||
125 | /** |
|
126 | * Opens a Socket connected to a remote host at the specified port and |
|
127 | * originating from the current host at a system assigned port. |
|
128 | * Before returning, {@link #_connectAction_ _connectAction_() } |
|
129 | * is called to perform connection initialization actions. |
|
130 | * <p> |
|
131 | * @param host The remote host. |
|
132 | * @param port The port to connect to on the remote host. |
|
133 | * @exception SocketException If the socket timeout could not be set. |
|
134 | * @exception IOException If the socket could not be opened. In most |
|
135 | * cases you will only want to catch IOException since SocketException is |
|
136 | * derived from it. |
|
137 | */ |
|
138 | public void connect(InetAddress host, int port) |
|
139 | throws SocketException, IOException |
|
140 | { |
|
141 | 2 | _socket_ = _socketFactory_.createSocket(host, port); |
142 | 2 | _connectAction_(); |
143 | 2 | } |
144 | ||
145 | /** |
|
146 | * Opens a Socket connected to a remote host at the specified port and |
|
147 | * originating from the current host at a system assigned port. |
|
148 | * Before returning, {@link #_connectAction_ _connectAction_() } |
|
149 | * is called to perform connection initialization actions. |
|
150 | * <p> |
|
151 | * @param hostname The name of the remote host. |
|
152 | * @param port The port to connect to on the remote host. |
|
153 | * @exception SocketException If the socket timeout could not be set. |
|
154 | * @exception IOException If the socket could not be opened. In most |
|
155 | * cases you will only want to catch IOException since SocketException is |
|
156 | * derived from it. |
|
157 | * @exception UnknownHostException If the hostname cannot be resolved. |
|
158 | */ |
|
159 | public void connect(String hostname, int port) |
|
160 | throws SocketException, IOException |
|
161 | { |
|
162 | 32 | _socket_ = _socketFactory_.createSocket(hostname, port); |
163 | 32 | _connectAction_(); |
164 | 32 | } |
165 | ||
166 | ||
167 | /** |
|
168 | * Opens a Socket connected to a remote host at the specified port and |
|
169 | * originating from the specified local address and port. |
|
170 | * Before returning, {@link #_connectAction_ _connectAction_() } |
|
171 | * is called to perform connection initialization actions. |
|
172 | * <p> |
|
173 | * @param host The remote host. |
|
174 | * @param port The port to connect to on the remote host. |
|
175 | * @param localAddr The local address to use. |
|
176 | * @param localPort The local port to use. |
|
177 | * @exception SocketException If the socket timeout could not be set. |
|
178 | * @exception IOException If the socket could not be opened. In most |
|
179 | * cases you will only want to catch IOException since SocketException is |
|
180 | * derived from it. |
|
181 | */ |
|
182 | public void connect(InetAddress host, int port, |
|
183 | InetAddress localAddr, int localPort) |
|
184 | throws SocketException, IOException |
|
185 | { |
|
186 | 0 | _socket_ = _socketFactory_.createSocket(host, port, localAddr, localPort); |
187 | 0 | _connectAction_(); |
188 | 0 | } |
189 | ||
190 | ||
191 | /** |
|
192 | * Opens a Socket connected to a remote host at the specified port and |
|
193 | * originating from the specified local address and port. |
|
194 | * Before returning, {@link #_connectAction_ _connectAction_() } |
|
195 | * is called to perform connection initialization actions. |
|
196 | * <p> |
|
197 | * @param hostname The name of the remote host. |
|
198 | * @param port The port to connect to on the remote host. |
|
199 | * @param localAddr The local address to use. |
|
200 | * @param localPort The local port to use. |
|
201 | * @exception SocketException If the socket timeout could not be set. |
|
202 | * @exception IOException If the socket could not be opened. In most |
|
203 | * cases you will only want to catch IOException since SocketException is |
|
204 | * derived from it. |
|
205 | * @exception UnknownHostException If the hostname cannot be resolved. |
|
206 | */ |
|
207 | public void connect(String hostname, int port, |
|
208 | InetAddress localAddr, int localPort) |
|
209 | throws SocketException, IOException |
|
210 | { |
|
211 | 0 | _socket_ = |
212 | _socketFactory_.createSocket(hostname, port, localAddr, localPort); |
|
213 | 0 | _connectAction_(); |
214 | 0 | } |
215 | ||
216 | ||
217 | /** |
|
218 | * Opens a Socket connected to a remote host at the current default port |
|
219 | * and originating from the current host at a system assigned port. |
|
220 | * Before returning, {@link #_connectAction_ _connectAction_() } |
|
221 | * is called to perform connection initialization actions. |
|
222 | * <p> |
|
223 | * @param host The remote host. |
|
224 | * @exception SocketException If the socket timeout could not be set. |
|
225 | * @exception IOException If the socket could not be opened. In most |
|
226 | * cases you will only want to catch IOException since SocketException is |
|
227 | * derived from it. |
|
228 | */ |
|
229 | public void connect(InetAddress host) throws SocketException, IOException |
|
230 | { |
|
231 | 0 | connect(host, _defaultPort_); |
232 | 0 | } |
233 | ||
234 | ||
235 | /** |
|
236 | * Opens a Socket connected to a remote host at the current default |
|
237 | * port and originating from the current host at a system assigned port. |
|
238 | * Before returning, {@link #_connectAction_ _connectAction_() } |
|
239 | * is called to perform connection initialization actions. |
|
240 | * <p> |
|
241 | * @param hostname The name of the remote host. |
|
242 | * @exception SocketException If the socket timeout could not be set. |
|
243 | * @exception IOException If the socket could not be opened. In most |
|
244 | * cases you will only want to catch IOException since SocketException is |
|
245 | * derived from it. |
|
246 | * @exception UnknownHostException If the hostname cannot be resolved. |
|
247 | */ |
|
248 | public void connect(String hostname) throws SocketException, IOException |
|
249 | { |
|
250 | 0 | connect(hostname, _defaultPort_); |
251 | 0 | } |
252 | ||
253 | ||
254 | /** |
|
255 | * Disconnects the socket connection. |
|
256 | * You should call this method after you've finished using the class |
|
257 | * instance and also before you call |
|
258 | * {@link #connect connect() } |
|
259 | * again. _isConnected_ is set to false, _socket_ is set to null, |
|
260 | * _input_ is set to null, and _output_ is set to null. |
|
261 | * <p> |
|
262 | * @exception IOException If there is an error closing the socket. |
|
263 | */ |
|
264 | public void disconnect() throws IOException |
|
265 | { |
|
266 | 34 | _socket_.close(); |
267 | 34 | _input_.close(); |
268 | 34 | _output_.close(); |
269 | 34 | _socket_ = null; |
270 | 34 | _input_ = null; |
271 | 34 | _output_ = null; |
272 | 34 | _isConnected_ = false; |
273 | 34 | } |
274 | ||
275 | ||
276 | /** |
|
277 | * Returns true if the client is currently connected to a server. |
|
278 | * <p> |
|
279 | * @return True if the client is currently connected to a server, |
|
280 | * false otherwise. |
|
281 | */ |
|
282 | public boolean isConnected() |
|
283 | { |
|
284 | 24 | return _isConnected_; |
285 | } |
|
286 | ||
287 | ||
288 | /** |
|
289 | * Sets the default port the SocketClient should connect to when a port |
|
290 | * is not specified. The {@link #_defaultPort_ _defaultPort_ } |
|
291 | * variable stores this value. If never set, the default port is equal |
|
292 | * to zero. |
|
293 | * <p> |
|
294 | * @param port The default port to set. |
|
295 | */ |
|
296 | public void setDefaultPort(int port) |
|
297 | { |
|
298 | 33 | _defaultPort_ = port; |
299 | 33 | } |
300 | ||
301 | /** |
|
302 | * Returns the current value of the default port (stored in |
|
303 | * {@link #_defaultPort_ _defaultPort_ }). |
|
304 | * <p> |
|
305 | * @return The current value of the default port. |
|
306 | */ |
|
307 | public int getDefaultPort() |
|
308 | { |
|
309 | 0 | return _defaultPort_; |
310 | } |
|
311 | ||
312 | ||
313 | /** |
|
314 | * Set the default timeout in milliseconds to use when opening a socket. |
|
315 | * This value is only used previous to a call to |
|
316 | * {@link #connect connect()} |
|
317 | * and should not be confused with {@link #setSoTimeout setSoTimeout()} |
|
318 | * which operates on an the currently opened socket. _timeout_ contains |
|
319 | * the new timeout value. |
|
320 | * <p> |
|
321 | * @param timeout The timeout in milliseconds to use for the socket |
|
322 | * connection. |
|
323 | */ |
|
324 | public void setDefaultTimeout(int timeout) |
|
325 | { |
|
326 | 2 | _timeout_ = timeout; |
327 | 2 | } |
328 | ||
329 | ||
330 | /** |
|
331 | * Returns the default timeout in milliseconds that is used when |
|
332 | * opening a socket. |
|
333 | * <p> |
|
334 | * @return The default timeout in milliseconds that is used when |
|
335 | * opening a socket. |
|
336 | */ |
|
337 | public int getDefaultTimeout() |
|
338 | { |
|
339 | 0 | return _timeout_; |
340 | } |
|
341 | ||
342 | ||
343 | /** |
|
344 | * Set the timeout in milliseconds of a currently open connection. |
|
345 | * Only call this method after a connection has been opened |
|
346 | * by {@link #connect connect()}. |
|
347 | * <p> |
|
348 | * @param timeout The timeout in milliseconds to use for the currently |
|
349 | * open socket connection. |
|
350 | * @exception SocketException If the operation fails. |
|
351 | */ |
|
352 | public void setSoTimeout(int timeout) throws SocketException |
|
353 | { |
|
354 | 0 | _socket_.setSoTimeout(timeout); |
355 | 0 | } |
356 | ||
357 | ||
358 | /** |
|
359 | * Returns the timeout in milliseconds of the currently opened socket. |
|
360 | * <p> |
|
361 | * @return The timeout in milliseconds of the currently opened socket. |
|
362 | * @exception SocketException If the operation fails. |
|
363 | */ |
|
364 | public int getSoTimeout() throws SocketException |
|
365 | { |
|
366 | 0 | return _socket_.getSoTimeout(); |
367 | } |
|
368 | ||
369 | /** |
|
370 | * Enables or disables the Nagle's algorithm (TCP_NODELAY) on the |
|
371 | * currently opened socket. |
|
372 | * <p> |
|
373 | * @param on True if Nagle's algorithm is to be enabled, false if not. |
|
374 | * @exception SocketException If the operation fails. |
|
375 | */ |
|
376 | public void setTcpNoDelay(boolean on) throws SocketException |
|
377 | { |
|
378 | 0 | _socket_.setTcpNoDelay(on); |
379 | 0 | } |
380 | ||
381 | ||
382 | /** |
|
383 | * Returns true if Nagle's algorithm is enabled on the currently opened |
|
384 | * socket. |
|
385 | * <p> |
|
386 | * @return True if Nagle's algorithm is enabled on the currently opened |
|
387 | * socket, false otherwise. |
|
388 | * @exception SocketException If the operation fails. |
|
389 | */ |
|
390 | public boolean getTcpNoDelay() throws SocketException |
|
391 | { |
|
392 | 0 | return _socket_.getTcpNoDelay(); |
393 | } |
|
394 | ||
395 | ||
396 | /** |
|
397 | * Sets the SO_LINGER timeout on the currently opened socket. |
|
398 | * <p> |
|
399 | * @param on True if linger is to be enabled, false if not. |
|
400 | * @param val The linger timeout (in hundredths of a second?) |
|
401 | * @exception SocketException If the operation fails. |
|
402 | */ |
|
403 | public void setSoLinger(boolean on, int val) throws SocketException |
|
404 | { |
|
405 | 0 | _socket_.setSoLinger(on, val); |
406 | 0 | } |
407 | ||
408 | ||
409 | /** |
|
410 | * Returns the current SO_LINGER timeout of the currently opened socket. |
|
411 | * <p> |
|
412 | * @return The current SO_LINGER timeout. If SO_LINGER is disabled returns |
|
413 | * -1. |
|
414 | * @exception SocketException If the operation fails. |
|
415 | */ |
|
416 | public int getSoLinger() throws SocketException |
|
417 | { |
|
418 | 0 | return _socket_.getSoLinger(); |
419 | } |
|
420 | ||
421 | ||
422 | /** |
|
423 | * Returns the port number of the open socket on the local host used |
|
424 | * for the connection. |
|
425 | * <p> |
|
426 | * @return The port number of the open socket on the local host used |
|
427 | * for the connection. |
|
428 | */ |
|
429 | public int getLocalPort() |
|
430 | { |
|
431 | 0 | return _socket_.getLocalPort(); |
432 | } |
|
433 | ||
434 | ||
435 | /** |
|
436 | * Returns the local address to which the client's socket is bound. |
|
437 | * <p> |
|
438 | * @return The local address to which the client's socket is bound. |
|
439 | */ |
|
440 | public InetAddress getLocalAddress() |
|
441 | { |
|
442 | 0 | return _socket_.getLocalAddress(); |
443 | } |
|
444 | ||
445 | /** |
|
446 | * Returns the port number of the remote host to which the client is |
|
447 | * connected. |
|
448 | * <p> |
|
449 | * @return The port number of the remote host to which the client is |
|
450 | * connected. |
|
451 | */ |
|
452 | public int getRemotePort() |
|
453 | { |
|
454 | 0 | return _socket_.getPort(); |
455 | } |
|
456 | ||
457 | ||
458 | /** |
|
459 | * @return The remote address to which the client is connected. |
|
460 | */ |
|
461 | public InetAddress getRemoteAddress() |
|
462 | { |
|
463 | 0 | return _socket_.getInetAddress(); |
464 | } |
|
465 | ||
466 | ||
467 | /** |
|
468 | * Verifies that the remote end of the given socket is connected to the |
|
469 | * the same host that the SocketClient is currently connected to. This |
|
470 | * is useful for doing a quick security check when a client needs to |
|
471 | * accept a connection from a server, such as an FTP data connection or |
|
472 | * a BSD R command standard error stream. |
|
473 | * <p> |
|
474 | * @return True if the remote hosts are the same, false if not. |
|
475 | */ |
|
476 | public boolean verifyRemote(Socket socket) |
|
477 | { |
|
478 | InetAddress host1, host2; |
|
479 | ||
480 | 0 | host1 = socket.getInetAddress(); |
481 | 0 | host2 = getRemoteAddress(); |
482 | ||
483 | 0 | return host1.equals(host2); |
484 | } |
|
485 | ||
486 | ||
487 | /** |
|
488 | * Sets the SocketFactory used by the SocketClient to open socket |
|
489 | * connections. If the factory value is null, then a default |
|
490 | * factory is used (only do this to reset the factory after having |
|
491 | * previously altered it). |
|
492 | * <p> |
|
493 | * @param factory The new SocketFactory the SocketClient should use. |
|
494 | */ |
|
495 | public void setSocketFactory(SocketFactory factory) |
|
496 | { |
|
497 | 0 | if (factory == null) |
498 | 0 | _socketFactory_ = __DEFAULT_SOCKET_FACTORY; |
499 | else |
|
500 | 0 | _socketFactory_ = factory; |
501 | 0 | } |
502 | } |
|
503 | ||
504 |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |