KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > 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 JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.OutputStream JavaDoc;
21 import java.net.InetAddress JavaDoc;
22 import java.net.Socket JavaDoc;
23 import java.net.SocketException JavaDoc;
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 JavaDoc NETASCII_EOL = "\r\n";
53
54     /** The default SocketFactory shared by all SocketClient instances. */
55     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 JavaDoc _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 JavaDoc _input_;
74
75     /** The socket's OutputStream. */
76     protected OutputStream JavaDoc _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     {
90         _socket_ = null;
91         _input_ = null;
92         _output_ = null;
93         _timeout_ = 0;
94         _defaultPort_ = 0;
95         _isConnected_ = false;
96         _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
97     }
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 JavaDoc
117     {
118         _socket_.setSoTimeout(_timeout_);
119         _input_ = _socket_.getInputStream();
120         _output_ = _socket_.getOutputStream();
121         _isConnected_ = true;
122     }
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 JavaDoc host, int port)
139     throws SocketException JavaDoc, IOException JavaDoc
140     {
141         _socket_ = _socketFactory_.createSocket(host, port);
142         _connectAction_();
143     }
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 JavaDoc hostname, int port)
160     throws SocketException JavaDoc, IOException JavaDoc
161     {
162         _socket_ = _socketFactory_.createSocket(hostname, port);
163         _connectAction_();
164     }
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 JavaDoc host, int port,
183                         InetAddress JavaDoc localAddr, int localPort)
184     throws SocketException JavaDoc, IOException JavaDoc
185     {
186         _socket_ = _socketFactory_.createSocket(host, port, localAddr, localPort);
187         _connectAction_();
188     }
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 JavaDoc hostname, int port,
208                         InetAddress JavaDoc localAddr, int localPort)
209     throws SocketException JavaDoc, IOException JavaDoc
210     {
211         _socket_ =
212             _socketFactory_.createSocket(hostname, port, localAddr, localPort);
213         _connectAction_();
214     }
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 JavaDoc host) throws SocketException JavaDoc, IOException JavaDoc
230     {
231         connect(host, _defaultPort_);
232     }
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 JavaDoc hostname) throws SocketException JavaDoc, IOException JavaDoc
249     {
250         connect(hostname, _defaultPort_);
251     }
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 JavaDoc
265     {
266         _socket_.close();
267         _input_.close();
268         _output_.close();
269         _socket_ = null;
270         _input_ = null;
271         _output_ = null;
272         _isConnected_ = false;
273     }
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         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         _defaultPort_ = port;
299     }
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         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         _timeout_ = timeout;
327     }
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         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 JavaDoc
353     {
354         _socket_.setSoTimeout(timeout);
355     }
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 JavaDoc
365     {
366         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 JavaDoc
377     {
378         _socket_.setTcpNoDelay(on);
379     }
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 JavaDoc
391     {
392         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 JavaDoc
404     {
405         _socket_.setSoLinger(on, val);
406     }
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 JavaDoc
417     {
418         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         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 JavaDoc getLocalAddress()
441     {
442         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         return _socket_.getPort();
455     }
456
457
458     /**
459      * @return The remote address to which the client is connected.
460      */

461     public InetAddress JavaDoc getRemoteAddress()
462     {
463         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 JavaDoc socket)
477     {
478         InetAddress JavaDoc host1, host2;
479
480         host1 = socket.getInetAddress();
481         host2 = getRemoteAddress();
482
483         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         if (factory == null)
498             _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
499         else
500             _socketFactory_ = factory;
501     }
502 }
503
504
505
Popular Tags