/ojc-core/ftpbc/ftpbcimpl/src/org/apache/commons/net/SocketClient.java

https://bitbucket.org/ssteinmetz/openesb-components · Java · 504 lines · 156 code · 62 blank · 286 comment · 2 complexity · feda2420b9371a03b6ae127346afcd39 MD5 · raw file

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