PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/classpath/java/net/Socket.java

https://bitbucket.org/thelearninglabs/uclinux-distro-tll-public
Java | 1288 lines | 504 code | 135 blank | 649 comment | 94 complexity | 954f28fb4b6122f3f9c9c8a9695c3eac MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-3.0, Unlicense, GPL-2.0, GPL-3.0, CC-BY-SA-3.0, AGPL-1.0, ISC, MIT, 0BSD, LGPL-2.0
  1. /* Socket.java -- Client socket implementation
  2. Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006, 2007
  3. Free Software Foundation, Inc.
  4. This file is part of GNU Classpath.
  5. GNU Classpath is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9. GNU Classpath is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GNU Classpath; see the file COPYING. If not, write to the
  15. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301 USA.
  17. Linking this library statically or dynamically with other modules is
  18. making a combined work based on this library. Thus, the terms and
  19. conditions of the GNU General Public License cover the whole
  20. combination.
  21. As a special exception, the copyright holders of this library give you
  22. permission to link this library with independent modules to produce an
  23. executable, regardless of the license terms of these independent
  24. modules, and to copy and distribute the resulting executable under
  25. terms of your choice, provided that you also meet, for each linked
  26. independent module, the terms and conditions of the license of that
  27. module. An independent module is a module which is not derived from
  28. or based on this library. If you modify this library, you may extend
  29. this exception to your version of the library, but you are not
  30. obligated to do so. If you do not wish to do so, delete this
  31. exception statement from your version. */
  32. package java.net;
  33. import gnu.java.net.PlainSocketImpl;
  34. import java.io.IOException;
  35. import java.io.InputStream;
  36. import java.io.OutputStream;
  37. import java.nio.channels.IllegalBlockingModeException;
  38. import java.nio.channels.SocketChannel;
  39. /* Written using on-line Java Platform 1.2 API Specification.
  40. * Status: I believe all methods are implemented.
  41. */
  42. /**
  43. * This class models a client site socket. A socket is a TCP/IP endpoint
  44. * for network communications conceptually similar to a file handle.
  45. * <p>
  46. * This class does not actually do any work. Instead, it redirects all of
  47. * its calls to a socket implementation object which implements the
  48. * <code>SocketImpl</code> interface. The implementation class is
  49. * instantiated by factory class that implements the
  50. * <code>SocketImplFactory interface</code>. A default
  51. * factory is provided, however the factory may be set by a call to
  52. * the <code>setSocketImplFactory</code> method. Note that this may only be
  53. * done once per virtual machine. If a subsequent attempt is made to set the
  54. * factory, a <code>SocketException</code> will be thrown.
  55. *
  56. * @author Aaron M. Renn (arenn@urbanophile.com)
  57. * @author Per Bothner (bothner@cygnus.com)
  58. */
  59. public class Socket
  60. {
  61. /**
  62. * This is the user SocketImplFactory for this class. If this variable is
  63. * null, a default factory is used.
  64. */
  65. static SocketImplFactory factory;
  66. /**
  67. * The implementation object to which calls are redirected
  68. */
  69. // package-private because ServerSocket.implAccept() needs to access it.
  70. SocketImpl impl;
  71. /**
  72. * True if impl.create() has been called.
  73. */
  74. // package-private because ServerSocket.implAccept() needs to access it.
  75. boolean implCreated;
  76. /**
  77. * True if the socket is bound.
  78. * Package private so it can be set from ServerSocket when accept is called.
  79. */
  80. boolean bound;
  81. /**
  82. * True if input is shutdown.
  83. */
  84. private boolean inputShutdown;
  85. /**
  86. * True if output is shutdown.
  87. */
  88. private boolean outputShutdown;
  89. /**
  90. * Initializes a new instance of <code>Socket</code> object without
  91. * connecting to a remote host. This useful for subclasses of socket that
  92. * might want this behavior.
  93. *
  94. * @specnote This constructor is public since JDK 1.4
  95. * @since 1.1
  96. */
  97. public Socket()
  98. {
  99. if (factory != null)
  100. impl = factory.createSocketImpl();
  101. else
  102. impl = new PlainSocketImpl();
  103. }
  104. /**
  105. * Initializes a new instance of <code>Socket</code> object without
  106. * connecting to a remote host. This is useful for subclasses of socket
  107. * that might want this behavior.
  108. * <p>
  109. * Additionally, this socket will be created using the supplied
  110. * implementation class instead the default class or one returned by a
  111. * factory. If this value is <code>null</code>, the default Socket
  112. * implementation is used.
  113. *
  114. * @param impl The <code>SocketImpl</code> to use for this
  115. * <code>Socket</code>
  116. *
  117. * @exception SocketException If an error occurs
  118. *
  119. * @since 1.1
  120. */
  121. protected Socket(SocketImpl impl) throws SocketException
  122. {
  123. if (impl == null)
  124. this.impl = new PlainSocketImpl();
  125. else
  126. this.impl = impl;
  127. }
  128. /**
  129. * Initializes a new instance of <code>Socket</code> and connects to the
  130. * hostname and port specified as arguments.
  131. *
  132. * @param host The name of the host to connect to
  133. * @param port The port number to connect to
  134. *
  135. * @exception UnknownHostException If the hostname cannot be resolved to a
  136. * network address.
  137. * @exception IOException If an error occurs
  138. * @exception SecurityException If a security manager exists and its
  139. * checkConnect method doesn't allow the operation
  140. */
  141. public Socket(String host, int port)
  142. throws UnknownHostException, IOException
  143. {
  144. this(InetAddress.getByName(host), port, null, 0, true);
  145. }
  146. /**
  147. * Initializes a new instance of <code>Socket</code> and connects to the
  148. * address and port number specified as arguments.
  149. *
  150. * @param address The address to connect to
  151. * @param port The port number to connect to
  152. *
  153. * @exception IOException If an error occurs
  154. * @exception SecurityException If a security manager exists and its
  155. * checkConnect method doesn't allow the operation
  156. */
  157. public Socket(InetAddress address, int port) throws IOException
  158. {
  159. this(address, port, null, 0, true);
  160. }
  161. /**
  162. * Initializes a new instance of <code>Socket</code> that connects to the
  163. * named host on the specified port and binds to the specified local address
  164. * and port.
  165. *
  166. * @param host The name of the remote host to connect to.
  167. * @param port The remote port to connect to.
  168. * @param localAddr The local address to bind to.
  169. * @param localPort The local port to bind to.
  170. *
  171. * @exception SecurityException If the <code>SecurityManager</code>
  172. * exists and does not allow a connection to the specified host/port or
  173. * binding to the specified local host/port.
  174. * @exception IOException If a connection error occurs.
  175. *
  176. * @since 1.1
  177. */
  178. public Socket(String host, int port, InetAddress localAddr, int localPort)
  179. throws IOException
  180. {
  181. this(InetAddress.getByName(host), port, localAddr, localPort, true);
  182. }
  183. /**
  184. * Initializes a new instance of <code>Socket</code> and connects to the
  185. * address and port number specified as arguments, plus binds to the
  186. * specified local address and port.
  187. *
  188. * @param address The remote address to connect to
  189. * @param port The remote port to connect to
  190. * @param localAddr The local address to connect to
  191. * @param localPort The local port to connect to
  192. *
  193. * @exception IOException If an error occurs
  194. * @exception SecurityException If a security manager exists and its
  195. * checkConnect method doesn't allow the operation
  196. *
  197. * @since 1.1
  198. */
  199. public Socket(InetAddress address, int port, InetAddress localAddr,
  200. int localPort) throws IOException
  201. {
  202. this(address, port, localAddr, localPort, true);
  203. }
  204. /**
  205. * Initializes a new instance of <code>Socket</code> and connects to the
  206. * hostname and port specified as arguments. If the stream argument is set
  207. * to <code>true</code>, then a stream socket is created. If it is
  208. * <code>false</code>, a datagram socket is created.
  209. *
  210. * @param host The name of the host to connect to
  211. * @param port The port to connect to
  212. * @param stream <code>true</code> for a stream socket, <code>false</code>
  213. * for a datagram socket
  214. *
  215. * @exception IOException If an error occurs
  216. * @exception SecurityException If a security manager exists and its
  217. * checkConnect method doesn't allow the operation
  218. *
  219. * @deprecated Use the <code>DatagramSocket</code> class to create
  220. * datagram oriented sockets.
  221. */
  222. public Socket(String host, int port, boolean stream)
  223. throws IOException
  224. {
  225. this(InetAddress.getByName(host), port, null, 0, stream);
  226. }
  227. /**
  228. * Initializes a new instance of <code>Socket</code> and connects to the
  229. * address and port number specified as arguments. If the stream param is
  230. * <code>true</code>, a stream socket will be created, otherwise a datagram
  231. * socket is created.
  232. *
  233. * @param host The address to connect to
  234. * @param port The port number to connect to
  235. * @param stream <code>true</code> to create a stream socket,
  236. * <code>false</code> to create a datagram socket.
  237. *
  238. * @exception IOException If an error occurs
  239. * @exception SecurityException If a security manager exists and its
  240. * checkConnect method doesn't allow the operation
  241. *
  242. * @deprecated Use the <code>DatagramSocket</code> class to create
  243. * datagram oriented sockets.
  244. */
  245. public Socket(InetAddress host, int port, boolean stream)
  246. throws IOException
  247. {
  248. this(host, port, null, 0, stream);
  249. }
  250. /**
  251. * This constructor is where the real work takes place. Connect to the
  252. * specified address and port. Use default local values if not specified,
  253. * otherwise use the local host and port passed in. Create as stream or
  254. * datagram based on "stream" argument.
  255. * <p>
  256. *
  257. * @param raddr The remote address to connect to
  258. * @param rport The remote port to connect to
  259. * @param laddr The local address to connect to
  260. * @param lport The local port to connect to
  261. * @param stream true for a stream socket, false for a datagram socket
  262. *
  263. * @exception IOException If an error occurs
  264. * @exception SecurityException If a security manager exists and its
  265. * checkConnect method doesn't allow the operation
  266. */
  267. private Socket(InetAddress raddr, int rport, InetAddress laddr, int lport,
  268. boolean stream) throws IOException
  269. {
  270. this();
  271. SecurityManager sm = System.getSecurityManager();
  272. if (sm != null)
  273. sm.checkConnect(raddr.getHostAddress(), rport);
  274. // bind socket
  275. SocketAddress bindaddr =
  276. laddr == null ? null : new InetSocketAddress(laddr, lport);
  277. bind(bindaddr);
  278. // Connect socket in case of Exceptions we must close the socket
  279. // because an exception in the constructor means that the caller will
  280. // not have a reference to this instance.
  281. // Note: You may have the idea that the exception treatment
  282. // should be moved into connect() but there is a Mauve test which
  283. // shows that a failed connect should not close the socket.
  284. try
  285. {
  286. connect(new InetSocketAddress(raddr, rport));
  287. }
  288. catch (IOException ioe)
  289. {
  290. impl.close();
  291. throw ioe;
  292. }
  293. catch (RuntimeException re)
  294. {
  295. impl.close();
  296. throw re;
  297. }
  298. // FIXME: JCL p. 1586 says if localPort is unspecified, bind to any port,
  299. // i.e. '0' and if localAddr is unspecified, use getLocalAddress() as
  300. // that default. JDK 1.2 doc infers not to do a bind.
  301. }
  302. private SocketImpl getImpl() throws SocketException
  303. {
  304. if (! implCreated)
  305. {
  306. try
  307. {
  308. impl.create(true);
  309. }
  310. catch (IOException x)
  311. {
  312. throw (SocketException) new SocketException().initCause(x);
  313. }
  314. implCreated = true;
  315. }
  316. return impl;
  317. }
  318. /**
  319. * Binds the socket to the given local address/port
  320. *
  321. * @param bindpoint The address/port to bind to
  322. *
  323. * @exception IOException If an error occurs
  324. * @exception SecurityException If a security manager exists and its
  325. * checkConnect method doesn't allow the operation
  326. * @exception IllegalArgumentException If the address type is not supported
  327. *
  328. * @since 1.4
  329. */
  330. public void bind(SocketAddress bindpoint) throws IOException
  331. {
  332. if (isClosed())
  333. throw new SocketException("socket is closed");
  334. // XXX: JDK 1.4.1 API documentation says that if bindpoint is null the
  335. // socket will be bound to an ephemeral port and a valid local address.
  336. if (bindpoint == null)
  337. bindpoint = new InetSocketAddress(InetAddress.ANY_IF, 0);
  338. if (! (bindpoint instanceof InetSocketAddress))
  339. throw new IllegalArgumentException();
  340. InetSocketAddress tmp = (InetSocketAddress) bindpoint;
  341. // bind to address/port
  342. try
  343. {
  344. getImpl().bind(tmp.getAddress(), tmp.getPort());
  345. bound = true;
  346. }
  347. catch (IOException exception)
  348. {
  349. close();
  350. throw exception;
  351. }
  352. catch (RuntimeException exception)
  353. {
  354. close();
  355. throw exception;
  356. }
  357. catch (Error error)
  358. {
  359. close();
  360. throw error;
  361. }
  362. }
  363. /**
  364. * Connects the socket with a remote address.
  365. *
  366. * @param endpoint The address to connect to
  367. *
  368. * @exception IOException If an error occurs
  369. * @exception IllegalArgumentException If the addess type is not supported
  370. * @exception IllegalBlockingModeException If this socket has an associated
  371. * channel, and the channel is in non-blocking mode
  372. *
  373. * @since 1.4
  374. */
  375. public void connect(SocketAddress endpoint) throws IOException
  376. {
  377. connect(endpoint, 0);
  378. }
  379. /**
  380. * Connects the socket with a remote address. A timeout of zero is
  381. * interpreted as an infinite timeout. The connection will then block
  382. * until established or an error occurs.
  383. *
  384. * @param endpoint The address to connect to
  385. * @param timeout The length of the timeout in milliseconds, or
  386. * 0 to indicate no timeout.
  387. *
  388. * @exception IOException If an error occurs
  389. * @exception IllegalArgumentException If the address type is not supported
  390. * @exception IllegalBlockingModeException If this socket has an associated
  391. * channel, and the channel is in non-blocking mode
  392. * @exception SocketTimeoutException If the timeout is reached
  393. *
  394. * @since 1.4
  395. */
  396. public void connect(SocketAddress endpoint, int timeout)
  397. throws IOException
  398. {
  399. if (isClosed())
  400. throw new SocketException("socket is closed");
  401. if (! (endpoint instanceof InetSocketAddress))
  402. throw new IllegalArgumentException("unsupported address type");
  403. // The Sun spec says that if we have an associated channel and
  404. // it is in non-blocking mode, we throw an IllegalBlockingModeException.
  405. // However, in our implementation if the channel itself initiated this
  406. // operation, then we must honor it regardless of its blocking mode.
  407. if (getChannel() != null && ! getChannel().isBlocking()
  408. && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
  409. throw new IllegalBlockingModeException();
  410. if (! isBound())
  411. bind(null);
  412. getImpl().connect(endpoint, timeout);
  413. }
  414. /**
  415. * Returns the address of the remote end of the socket. If this socket
  416. * is not connected, then <code>null</code> is returned.
  417. *
  418. * @return The remote address this socket is connected to
  419. */
  420. public InetAddress getInetAddress()
  421. {
  422. if (! isConnected())
  423. return null;
  424. try
  425. {
  426. return getImpl().getInetAddress();
  427. }
  428. catch (SocketException e)
  429. {
  430. // This cannot happen as we are connected.
  431. }
  432. return null;
  433. }
  434. /**
  435. * Returns the local address to which this socket is bound. If this socket
  436. * is not connected, then a wildcard address, for which
  437. * @see InetAddress#isAnyLocalAddress() is <code>true</code>, is returned.
  438. *
  439. * @return The local address
  440. *
  441. * @since 1.1
  442. */
  443. public InetAddress getLocalAddress()
  444. {
  445. if (! isBound())
  446. return InetAddress.ANY_IF;
  447. InetAddress addr = null;
  448. if (impl instanceof PlainSocketImpl)
  449. addr = ((PlainSocketImpl) impl).getLocalAddress().getAddress();
  450. if (addr == null)
  451. {
  452. try
  453. {
  454. addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
  455. }
  456. catch (SocketException e)
  457. {
  458. // (hopefully) shouldn't happen
  459. // throw new java.lang.InternalError
  460. // ("Error in PlainSocketImpl.getOption");
  461. return null;
  462. }
  463. }
  464. // FIXME: According to libgcj, checkConnect() is supposed to be called
  465. // before performing this operation. Problems: 1) We don't have the
  466. // addr until after we do it, so we do a post check. 2). The docs I
  467. // see don't require this in the Socket case, only DatagramSocket, but
  468. // we'll assume they mean both.
  469. SecurityManager sm = System.getSecurityManager();
  470. if (sm != null)
  471. sm.checkConnect(addr.getHostName(), getLocalPort());
  472. return addr;
  473. }
  474. /**
  475. * Returns the port number of the remote end of the socket connection. If
  476. * this socket is not connected, then 0 is returned.
  477. *
  478. * @return The remote port this socket is connected to
  479. */
  480. public int getPort()
  481. {
  482. if (! isConnected())
  483. return 0;
  484. try
  485. {
  486. return getImpl().getPort();
  487. }
  488. catch (SocketException e)
  489. {
  490. // This cannot happen as we are connected.
  491. }
  492. return 0;
  493. }
  494. /**
  495. * Returns the local port number to which this socket is bound. If this
  496. * socket is not connected, then -1 is returned.
  497. *
  498. * @return The local port
  499. */
  500. public int getLocalPort()
  501. {
  502. if (! isBound())
  503. return -1;
  504. try
  505. {
  506. if (getImpl() != null)
  507. return getImpl().getLocalPort();
  508. }
  509. catch (SocketException e)
  510. {
  511. // This cannot happen as we are bound.
  512. }
  513. return -1;
  514. }
  515. /**
  516. * Returns local socket address.
  517. *
  518. * @return the local socket address, null if not bound
  519. *
  520. * @since 1.4
  521. */
  522. public SocketAddress getLocalSocketAddress()
  523. {
  524. if (! isBound())
  525. return null;
  526. InetAddress addr = getLocalAddress();
  527. try
  528. {
  529. return new InetSocketAddress(addr, getImpl().getLocalPort());
  530. }
  531. catch (SocketException e)
  532. {
  533. // This cannot happen as we are bound.
  534. return null;
  535. }
  536. }
  537. /**
  538. * Returns the remote socket address.
  539. *
  540. * @return the remote socket address, null of not connected
  541. *
  542. * @since 1.4
  543. */
  544. public SocketAddress getRemoteSocketAddress()
  545. {
  546. if (! isConnected())
  547. return null;
  548. try
  549. {
  550. return new InetSocketAddress(getImpl().getInetAddress(),
  551. getImpl().getPort());
  552. }
  553. catch (SocketException e)
  554. {
  555. // This cannot happen as we are connected.
  556. return null;
  557. }
  558. }
  559. /**
  560. * Returns an InputStream for reading from this socket.
  561. *
  562. * @return The InputStream object
  563. *
  564. * @exception IOException If an error occurs or Socket is not connected
  565. */
  566. public InputStream getInputStream() throws IOException
  567. {
  568. if (isClosed())
  569. throw new SocketException("socket is closed");
  570. if (! isConnected())
  571. throw new IOException("not connected");
  572. return getImpl().getInputStream();
  573. }
  574. /**
  575. * Returns an OutputStream for writing to this socket.
  576. *
  577. * @return The OutputStream object
  578. *
  579. * @exception IOException If an error occurs or Socket is not connected
  580. */
  581. public OutputStream getOutputStream() throws IOException
  582. {
  583. if (isClosed())
  584. throw new SocketException("socket is closed");
  585. if (! isConnected())
  586. throw new IOException("not connected");
  587. return getImpl().getOutputStream();
  588. }
  589. /**
  590. * Sets the TCP_NODELAY option on the socket.
  591. *
  592. * @param on true to enable, false to disable
  593. *
  594. * @exception SocketException If an error occurs or Socket is not connected
  595. *
  596. * @since 1.1
  597. */
  598. public void setTcpNoDelay(boolean on) throws SocketException
  599. {
  600. if (isClosed())
  601. throw new SocketException("socket is closed");
  602. getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
  603. }
  604. /**
  605. * Tests whether or not the TCP_NODELAY option is set on the socket.
  606. * Returns true if enabled, false if disabled. When on it disables the
  607. * Nagle algorithm which means that packets are always send immediatly and
  608. * never merged together to reduce network trafic.
  609. *
  610. * @return Whether or not TCP_NODELAY is set
  611. *
  612. * @exception SocketException If an error occurs or Socket not connected
  613. *
  614. * @since 1.1
  615. */
  616. public boolean getTcpNoDelay() throws SocketException
  617. {
  618. if (isClosed())
  619. throw new SocketException("socket is closed");
  620. Object on = getImpl().getOption(SocketOptions.TCP_NODELAY);
  621. if (on instanceof Boolean)
  622. return (((Boolean) on).booleanValue());
  623. else
  624. throw new SocketException("Internal Error");
  625. }
  626. /**
  627. * Sets the value of the SO_LINGER option on the socket. If the
  628. * SO_LINGER option is set on a socket and there is still data waiting to
  629. * be sent when the socket is closed, then the close operation will block
  630. * until either that data is delivered or until the timeout period
  631. * expires. The linger interval is specified in hundreths of a second
  632. * (platform specific?)
  633. *
  634. * @param on true to enable SO_LINGER, false to disable
  635. * @param linger The SO_LINGER timeout in hundreths of a second or -1 if
  636. * SO_LINGER not set.
  637. *
  638. * @exception SocketException If an error occurs or Socket not connected
  639. * @exception IllegalArgumentException If linger is negative
  640. *
  641. * @since 1.1
  642. */
  643. public void setSoLinger(boolean on, int linger) throws SocketException
  644. {
  645. if (isClosed())
  646. throw new SocketException("socket is closed");
  647. if (on)
  648. {
  649. if (linger < 0)
  650. throw new IllegalArgumentException("SO_LINGER must be >= 0");
  651. if (linger > 65535)
  652. linger = 65535;
  653. getImpl().setOption(SocketOptions.SO_LINGER, Integer.valueOf(linger));
  654. }
  655. else
  656. getImpl().setOption(SocketOptions.SO_LINGER, Integer.valueOf(-1));
  657. }
  658. /**
  659. * Returns the value of the SO_LINGER option on the socket. If the
  660. * SO_LINGER option is set on a socket and there is still data waiting to
  661. * be sent when the socket is closed, then the close operation will block
  662. * until either that data is delivered or until the timeout period
  663. * expires. This method either returns the timeouts (in hundredths of
  664. * of a second (platform specific?)) if SO_LINGER is set, or -1 if
  665. * SO_LINGER is not set.
  666. *
  667. * @return The SO_LINGER timeout in hundreths of a second or -1
  668. * if SO_LINGER not set
  669. *
  670. * @exception SocketException If an error occurs or Socket is not connected
  671. *
  672. * @since 1.1
  673. */
  674. public int getSoLinger() throws SocketException
  675. {
  676. if (isClosed())
  677. throw new SocketException("socket is closed");
  678. Object linger = getImpl().getOption(SocketOptions.SO_LINGER);
  679. if (linger instanceof Integer)
  680. return (((Integer) linger).intValue());
  681. else
  682. return -1;
  683. }
  684. /**
  685. * Sends urgent data through the socket
  686. *
  687. * @param data The data to send.
  688. * Only the lowest eight bits of data are sent
  689. *
  690. * @exception IOException If an error occurs
  691. *
  692. * @since 1.4
  693. */
  694. public void sendUrgentData(int data) throws IOException
  695. {
  696. if (isClosed())
  697. throw new SocketException("socket is closed");
  698. getImpl().sendUrgentData(data);
  699. }
  700. /**
  701. * Enables/disables the SO_OOBINLINE option
  702. *
  703. * @param on True if SO_OOBLINE should be enabled
  704. *
  705. * @exception SocketException If an error occurs
  706. *
  707. * @since 1.4
  708. */
  709. public void setOOBInline(boolean on) throws SocketException
  710. {
  711. if (isClosed())
  712. throw new SocketException("socket is closed");
  713. getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
  714. }
  715. /**
  716. * Returns the current setting of the SO_OOBINLINE option for this socket
  717. *
  718. * @return True if SO_OOBINLINE is set, false otherwise.
  719. *
  720. * @exception SocketException If an error occurs
  721. *
  722. * @since 1.4
  723. */
  724. public boolean getOOBInline() throws SocketException
  725. {
  726. if (isClosed())
  727. throw new SocketException("socket is closed");
  728. Object buf = getImpl().getOption(SocketOptions.SO_OOBINLINE);
  729. if (buf instanceof Boolean)
  730. return (((Boolean) buf).booleanValue());
  731. else
  732. throw new SocketException("Internal Error: Unexpected type");
  733. }
  734. /**
  735. * Sets the value of the SO_TIMEOUT option on the socket. If this value
  736. * is set, and an read/write is performed that does not complete within
  737. * the timeout period, a short count is returned (or an EWOULDBLOCK signal
  738. * would be sent in Unix if no data had been read). A value of 0 for
  739. * this option implies that there is no timeout (ie, operations will
  740. * block forever). On systems that have separate read and write timeout
  741. * values, this method returns the read timeout. This
  742. * value is in milliseconds.
  743. *
  744. * @param timeout The length of the timeout in milliseconds, or
  745. * 0 to indicate no timeout.
  746. *
  747. * @exception SocketException If an error occurs or Socket not connected
  748. *
  749. * @since 1.1
  750. */
  751. public synchronized void setSoTimeout(int timeout) throws SocketException
  752. {
  753. if (isClosed())
  754. throw new SocketException("socket is closed");
  755. if (timeout < 0)
  756. throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
  757. getImpl().setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
  758. }
  759. /**
  760. * Returns the value of the SO_TIMEOUT option on the socket. If this value
  761. * is set, and an read/write is performed that does not complete within
  762. * the timeout period, a short count is returned (or an EWOULDBLOCK signal
  763. * would be sent in Unix if no data had been read). A value of 0 for
  764. * this option implies that there is no timeout (ie, operations will
  765. * block forever). On systems that have separate read and write timeout
  766. * values, this method returns the read timeout. This
  767. * value is in thousandths of a second (implementation specific?).
  768. *
  769. * @return The length of the timeout in thousandth's of a second or 0
  770. * if not set
  771. *
  772. * @exception SocketException If an error occurs or Socket not connected
  773. *
  774. * @since 1.1
  775. */
  776. public synchronized int getSoTimeout() throws SocketException
  777. {
  778. if (isClosed())
  779. throw new SocketException("socket is closed");
  780. Object timeout = getImpl().getOption(SocketOptions.SO_TIMEOUT);
  781. if (timeout instanceof Integer)
  782. return (((Integer) timeout).intValue());
  783. else
  784. return 0;
  785. }
  786. /**
  787. * This method sets the value for the system level socket option
  788. * SO_SNDBUF to the specified value. Note that valid values for this
  789. * option are specific to a given operating system.
  790. *
  791. * @param size The new send buffer size.
  792. *
  793. * @exception SocketException If an error occurs or Socket not connected
  794. * @exception IllegalArgumentException If size is 0 or negative
  795. *
  796. * @since 1.2
  797. */
  798. public void setSendBufferSize(int size) throws SocketException
  799. {
  800. if (isClosed())
  801. throw new SocketException("socket is closed");
  802. if (size <= 0)
  803. throw new IllegalArgumentException("SO_SNDBUF value must be > 0");
  804. getImpl().setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
  805. }
  806. /**
  807. * This method returns the value of the system level socket option
  808. * SO_SNDBUF, which is used by the operating system to tune buffer
  809. * sizes for data transfers.
  810. *
  811. * @return The send buffer size.
  812. *
  813. * @exception SocketException If an error occurs or socket not connected
  814. *
  815. * @since 1.2
  816. */
  817. public int getSendBufferSize() throws SocketException
  818. {
  819. if (isClosed())
  820. throw new SocketException("socket is closed");
  821. Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);
  822. if (buf instanceof Integer)
  823. return (((Integer) buf).intValue());
  824. else
  825. throw new SocketException("Internal Error: Unexpected type");
  826. }
  827. /**
  828. * This method sets the value for the system level socket option
  829. * SO_RCVBUF to the specified value. Note that valid values for this
  830. * option are specific to a given operating system.
  831. *
  832. * @param size The new receive buffer size.
  833. *
  834. * @exception SocketException If an error occurs or Socket is not connected
  835. * @exception IllegalArgumentException If size is 0 or negative
  836. *
  837. * @since 1.2
  838. */
  839. public void setReceiveBufferSize(int size) throws SocketException
  840. {
  841. if (isClosed())
  842. throw new SocketException("socket is closed");
  843. if (size <= 0)
  844. throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
  845. getImpl().setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
  846. }
  847. /**
  848. * This method returns the value of the system level socket option
  849. * SO_RCVBUF, which is used by the operating system to tune buffer
  850. * sizes for data transfers.
  851. *
  852. * @return The receive buffer size.
  853. *
  854. * @exception SocketException If an error occurs or Socket is not connected
  855. *
  856. * @since 1.2
  857. */
  858. public int getReceiveBufferSize() throws SocketException
  859. {
  860. if (isClosed())
  861. throw new SocketException("socket is closed");
  862. Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);
  863. if (buf instanceof Integer)
  864. return (((Integer) buf).intValue());
  865. else
  866. throw new SocketException("Internal Error: Unexpected type");
  867. }
  868. /**
  869. * This method sets the value for the socket level socket option
  870. * SO_KEEPALIVE.
  871. *
  872. * @param on True if SO_KEEPALIVE should be enabled
  873. *
  874. * @exception SocketException If an error occurs or Socket is not connected
  875. *
  876. * @since 1.3
  877. */
  878. public void setKeepAlive(boolean on) throws SocketException
  879. {
  880. if (isClosed())
  881. throw new SocketException("socket is closed");
  882. getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
  883. }
  884. /**
  885. * This method returns the value of the socket level socket option
  886. * SO_KEEPALIVE.
  887. *
  888. * @return The setting
  889. *
  890. * @exception SocketException If an error occurs or Socket is not connected
  891. *
  892. * @since 1.3
  893. */
  894. public boolean getKeepAlive() throws SocketException
  895. {
  896. if (isClosed())
  897. throw new SocketException("socket is closed");
  898. Object buf = getImpl().getOption(SocketOptions.SO_KEEPALIVE);
  899. if (buf instanceof Boolean)
  900. return (((Boolean) buf).booleanValue());
  901. else
  902. throw new SocketException("Internal Error: Unexpected type");
  903. }
  904. /**
  905. * Closes the socket.
  906. *
  907. * @exception IOException If an error occurs
  908. */
  909. public synchronized void close() throws IOException
  910. {
  911. if (isClosed())
  912. return;
  913. impl.close();
  914. impl = null;
  915. }
  916. /**
  917. * Converts this <code>Socket</code> to a <code>String</code>.
  918. *
  919. * @return The <code>String</code> representation of this <code>Socket</code>
  920. */
  921. public String toString()
  922. {
  923. try
  924. {
  925. if (isConnected())
  926. return (super.toString()
  927. + " [addr=" + getImpl().getInetAddress() + ",port="
  928. + getImpl().getPort() + ",localport="
  929. + getImpl().getLocalPort() + "]");
  930. }
  931. catch (SocketException e)
  932. {
  933. // This cannot happen as we are connected.
  934. }
  935. return super.toString() + " [unconnected]";
  936. }
  937. /**
  938. * Sets the <code>SocketImplFactory</code>. This may be done only once per
  939. * virtual machine. Subsequent attempts will generate a
  940. * <code>SocketException</code>. Note that a <code>SecurityManager</code>
  941. * check is made prior to setting the factory. If
  942. * insufficient privileges exist to set the factory, then an
  943. * <code>IOException</code> will be thrown.
  944. *
  945. * @param fac the factory to set
  946. *
  947. * @exception SecurityException If the <code>SecurityManager</code> does
  948. * not allow this operation.
  949. * @exception SocketException If the SocketImplFactory is already defined
  950. * @exception IOException If any other error occurs
  951. */
  952. public static synchronized void setSocketImplFactory(SocketImplFactory fac)
  953. throws IOException
  954. {
  955. // See if already set
  956. if (factory != null)
  957. throw new SocketException("SocketImplFactory already defined");
  958. // Check permissions
  959. SecurityManager sm = System.getSecurityManager();
  960. if (sm != null)
  961. sm.checkSetFactory();
  962. if (fac == null)
  963. throw new SocketException("SocketImplFactory cannot be null");
  964. factory = fac;
  965. }
  966. /**
  967. * Closes the input side of the socket stream.
  968. *
  969. * @exception IOException If an error occurs.
  970. *
  971. * @since 1.3
  972. */
  973. public void shutdownInput() throws IOException
  974. {
  975. if (isClosed())
  976. throw new SocketException("socket is closed");
  977. getImpl().shutdownInput();
  978. inputShutdown = true;
  979. }
  980. /**
  981. * Closes the output side of the socket stream.
  982. *
  983. * @exception IOException If an error occurs.
  984. *
  985. * @since 1.3
  986. */
  987. public void shutdownOutput() throws IOException
  988. {
  989. if (isClosed())
  990. throw new SocketException("socket is closed");
  991. getImpl().shutdownOutput();
  992. outputShutdown = true;
  993. }
  994. /**
  995. * Returns the socket channel associated with this socket.
  996. *
  997. * @return the associated socket channel,
  998. * null if no associated channel exists
  999. *
  1000. * @since 1.4
  1001. */
  1002. public SocketChannel getChannel()
  1003. {
  1004. return null;
  1005. }
  1006. /**
  1007. * Checks if the SO_REUSEADDR option is enabled
  1008. *
  1009. * @return True if SO_REUSEADDR is set, false otherwise.
  1010. *
  1011. * @exception SocketException If an error occurs
  1012. *
  1013. * @since 1.4
  1014. */
  1015. public boolean getReuseAddress() throws SocketException
  1016. {
  1017. if (isClosed())
  1018. throw new SocketException("socket is closed");
  1019. Object reuseaddr = getImpl().getOption(SocketOptions.SO_REUSEADDR);
  1020. if (! (reuseaddr instanceof Boolean))
  1021. throw new SocketException("Internal Error");
  1022. return ((Boolean) reuseaddr).booleanValue();
  1023. }
  1024. /**
  1025. * Enables/Disables the SO_REUSEADDR option
  1026. *
  1027. * @param reuseAddress true if SO_REUSEADDR should be enabled,
  1028. * false otherwise
  1029. *
  1030. * @exception SocketException If an error occurs
  1031. *
  1032. * @since 1.4
  1033. */
  1034. public void setReuseAddress(boolean reuseAddress) throws SocketException
  1035. {
  1036. if (isClosed())
  1037. throw new SocketException("socket is closed");
  1038. getImpl().setOption(SocketOptions.SO_REUSEADDR,
  1039. Boolean.valueOf(reuseAddress));
  1040. }
  1041. /**
  1042. * Returns the current traffic class
  1043. *
  1044. * @return The current traffic class.
  1045. *
  1046. * @exception SocketException If an error occurs
  1047. *
  1048. * @see Socket#setTrafficClass(int tc)
  1049. *
  1050. * @since 1.4
  1051. */
  1052. public int getTrafficClass() throws SocketException
  1053. {
  1054. if (isClosed())
  1055. throw new SocketException("socket is closed");
  1056. Object obj = getImpl().getOption(SocketOptions.IP_TOS);
  1057. if (obj instanceof Integer)
  1058. return ((Integer) obj).intValue();
  1059. else
  1060. throw new SocketException("Unexpected type");
  1061. }
  1062. /**
  1063. * Sets the traffic class value
  1064. *
  1065. * @param tc The traffic class
  1066. *
  1067. * @exception SocketException If an error occurs
  1068. * @exception IllegalArgumentException If tc value is illegal
  1069. *
  1070. * @see Socket#getTrafficClass()
  1071. *
  1072. * @since 1.4
  1073. */
  1074. public void setTrafficClass(int tc) throws SocketException
  1075. {
  1076. if (isClosed())
  1077. throw new SocketException("socket is closed");
  1078. if (tc < 0 || tc > 255)
  1079. throw new IllegalArgumentException();
  1080. getImpl().setOption(SocketOptions.IP_TOS, Integer.valueOf(tc));
  1081. }
  1082. /**
  1083. * Checks if the socket is connected
  1084. *
  1085. * @return True if socket is connected, false otherwise.
  1086. *
  1087. * @since 1.4
  1088. */
  1089. public boolean isConnected()
  1090. {
  1091. if (impl == null)
  1092. return false;
  1093. return impl.getInetAddress() != null;
  1094. }
  1095. /**
  1096. * Checks if the socket is already bound.
  1097. *
  1098. * @return True if socket is bound, false otherwise.
  1099. *
  1100. * @since 1.4
  1101. */
  1102. public boolean isBound()
  1103. {
  1104. if (isClosed())
  1105. return false;
  1106. if (impl instanceof PlainSocketImpl)
  1107. {
  1108. InetSocketAddress addr = ((PlainSocketImpl) impl).getLocalAddress();
  1109. return addr != null && addr.getAddress() != null;
  1110. }
  1111. return bound;
  1112. }
  1113. /**
  1114. * Checks if the socket is closed.
  1115. *
  1116. * @return True if socket is closed, false otherwise.
  1117. *
  1118. * @since 1.4
  1119. */
  1120. public boolean isClosed()
  1121. {
  1122. SocketChannel channel = getChannel();
  1123. return impl == null || (channel != null && ! channel.isOpen());
  1124. }
  1125. /**
  1126. * Checks if the socket's input stream is shutdown
  1127. *
  1128. * @return True if input is shut down.
  1129. *
  1130. * @since 1.4
  1131. */
  1132. public boolean isInputShutdown()
  1133. {
  1134. return inputShutdown;
  1135. }
  1136. /**
  1137. * Checks if the socket's output stream is shutdown
  1138. *
  1139. * @return True if output is shut down.
  1140. *
  1141. * @since 1.4
  1142. */
  1143. public boolean isOutputShutdown()
  1144. {
  1145. return outputShutdown;
  1146. }
  1147. }