1. /*
  2. * @(#)DatagramSocket.java 1.90 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.net;
  8. import java.io.FileDescriptor;
  9. import java.io.IOException;
  10. import java.io.InterruptedIOException;
  11. import java.nio.channels.DatagramChannel;
  12. import java.security.AccessController;
  13. import java.security.PrivilegedExceptionAction;
  14. /**
  15. * This class represents a socket for sending and receiving datagram packets.
  16. *
  17. * <p>A datagram socket is the sending or receiving point for a packet
  18. * delivery service. Each packet sent or received on a datagram socket
  19. * is individually addressed and routed. Multiple packets sent from
  20. * one machine to another may be routed differently, and may arrive in
  21. * any order.
  22. *
  23. * <p>UDP broadcasts sends are always enabled on a DatagramSocket.
  24. * In order to receive broadcast packets a DatagramSocket
  25. * should be bound to the wildcard address. In some
  26. * implementations, broadcast packets may also be received when
  27. * a DatagramSocket is bound to a more specific address.
  28. * <p>
  29. * Example:
  30. * <code>
  31. * DatagramSocket s = new DatagramSocket(null);
  32. * s.bind(new InetSocketAddress(8888));
  33. * </code>
  34. * Which is equivalent to:
  35. * <code>
  36. * DatagramSocket s = new DatagramSocket(8888);
  37. * </code>
  38. * Both cases will create a DatagramSocket able to receive broadcasts on
  39. * UDP port 8888.
  40. *
  41. * @author Pavani Diwanji
  42. * @version 1.90, 01/23/03
  43. * @see java.net.DatagramPacket
  44. * @see java.nio.channels.DatagramChannel
  45. * @since JDK1.0
  46. */
  47. public
  48. class DatagramSocket {
  49. /**
  50. * Various states of this socket.
  51. */
  52. private boolean created = false;
  53. private boolean bound = false;
  54. private boolean closed = false;
  55. private Object closeLock = new Object();
  56. /*
  57. * The implementation of this DatagramSocket.
  58. */
  59. DatagramSocketImpl impl;
  60. /**
  61. * Are we using an older DatagramSocketImpl?
  62. */
  63. boolean oldImpl = false;
  64. /*
  65. * Connection state:
  66. * ST_NOT_CONNECTED = socket not connected
  67. * ST_CONNECTED = socket connected
  68. * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
  69. */
  70. static final int ST_NOT_CONNECTED = 0;
  71. static final int ST_CONNECTED = 1;
  72. static final int ST_CONNECTED_NO_IMPL = 2;
  73. int connectState = ST_NOT_CONNECTED;
  74. /*
  75. * Connected address & port
  76. */
  77. InetAddress connectedAddress = null;
  78. int connectedPort = -1;
  79. /**
  80. * Connects this socket to a remote socket address (IP address + port number).
  81. * Binds socket if not already bound.
  82. * <p>
  83. * @param addr The remote address.
  84. * @param port The remote port
  85. * @throws SocketException if binding the socket fails.
  86. */
  87. private synchronized void connectInternal(InetAddress address, int port) throws SocketException {
  88. if (port < 0 || port > 0xFFFF) {
  89. throw new IllegalArgumentException("connect: " + port);
  90. }
  91. if (address == null) {
  92. throw new IllegalArgumentException("connect: null address");
  93. }
  94. if (isClosed())
  95. return;
  96. SecurityManager security = System.getSecurityManager();
  97. if (security != null) {
  98. if (address.isMulticastAddress()) {
  99. security.checkMulticast(address);
  100. } else {
  101. security.checkConnect(address.getHostAddress(), port);
  102. security.checkAccept(address.getHostAddress(), port);
  103. }
  104. }
  105. if (!isBound())
  106. bind(new InetSocketAddress(0));
  107. // old impls do not support connect/disconnect
  108. if (oldImpl) {
  109. connectState = ST_CONNECTED_NO_IMPL;
  110. } else {
  111. try {
  112. getImpl().connect(address, port);
  113. // socket is now connected by the impl
  114. connectState = ST_CONNECTED;
  115. } catch (SocketException se) {
  116. // connection will be emulated by DatagramSocket
  117. connectState = ST_CONNECTED_NO_IMPL;
  118. }
  119. }
  120. connectedAddress = address;
  121. connectedPort = port;
  122. }
  123. /**
  124. * Constructs a datagram socket and binds it to any available port
  125. * on the local host machine. The socket will be bound to the wildcard
  126. * address, an IP address chosen by the kernel.
  127. *
  128. * <p>If there is a security manager,
  129. * its <code>checkListen</code> method is first called
  130. * with 0 as its argument to ensure the operation is allowed.
  131. * This could result in a SecurityException.
  132. *
  133. * @exception SocketException if the socket could not be opened,
  134. * or the socket could not bind to the specified local port.
  135. * @exception SecurityException if a security manager exists and its
  136. * <code>checkListen</code> method doesn't allow the operation.
  137. *
  138. * @see SecurityManager#checkListen
  139. */
  140. public DatagramSocket() throws SocketException {
  141. // create a datagram socket.
  142. createImpl();
  143. try {
  144. bind(new InetSocketAddress(0));
  145. } catch (SocketException se) {
  146. throw se;
  147. } catch(IOException e) {
  148. throw new SocketException(e.getMessage());
  149. }
  150. }
  151. /**
  152. * Creates an unbound datagram socket with the specified
  153. * DatagramSocketImpl.
  154. *
  155. * @param impl an instance of a <B>DatagramSocketImpl</B>
  156. * the subclass wishes to use on the DatagramSocket.
  157. * @since 1.4
  158. */
  159. protected DatagramSocket(DatagramSocketImpl impl) {
  160. if (impl == null)
  161. throw new NullPointerException();
  162. this.impl = impl;
  163. checkOldImpl();
  164. }
  165. /**
  166. * Creates a datagram socket, bound to the specified local
  167. * socket address.
  168. * <p>
  169. * If, if the address is <code>null</code>, creates an unbound socket.
  170. * <p>
  171. * <p>If there is a security manager,
  172. * its <code>checkListen</code> method is first called
  173. * with the port from the socket address
  174. * as its argument to ensure the operation is allowed.
  175. * This could result in a SecurityException.
  176. *
  177. * @param bindaddr local socket address to bind, or <code>null</code>
  178. * for an unbound socket.
  179. *
  180. * @exception SocketException if the socket could not be opened,
  181. * or the socket could not bind to the specified local port.
  182. * @exception SecurityException if a security manager exists and its
  183. * <code>checkListen</code> method doesn't allow the operation.
  184. *
  185. * @see SecurityManager#checkListen
  186. * @since 1.4
  187. */
  188. public DatagramSocket(SocketAddress bindaddr) throws SocketException {
  189. // create a datagram socket.
  190. createImpl();
  191. if (bindaddr != null) {
  192. bind(bindaddr);
  193. }
  194. }
  195. /**
  196. * Constructs a datagram socket and binds it to the specified port
  197. * on the local host machine. The socket will be bound to the wildcard
  198. * address, an IP address chosen by the kernel.
  199. *
  200. * <p>If there is a security manager,
  201. * its <code>checkListen</code> method is first called
  202. * with the <code>port</code> argument
  203. * as its argument to ensure the operation is allowed.
  204. * This could result in a SecurityException.
  205. *
  206. * @param port port to use.
  207. * @exception SocketException if the socket could not be opened,
  208. * or the socket could not bind to the specified local port.
  209. * @exception SecurityException if a security manager exists and its
  210. * <code>checkListen</code> method doesn't allow the operation.
  211. *
  212. * @see SecurityManager#checkListen
  213. */
  214. public DatagramSocket(int port) throws SocketException {
  215. this(port, null);
  216. }
  217. /**
  218. * Creates a datagram socket, bound to the specified local
  219. * address. The local port must be between 0 and 65535 inclusive.
  220. * If the IP address is 0.0.0.0, the socket will be bound to the
  221. * wildcard address, an IP address chosen by the kernel.
  222. *
  223. * <p>If there is a security manager,
  224. * its <code>checkListen</code> method is first called
  225. * with the <code>port</code> argument
  226. * as its argument to ensure the operation is allowed.
  227. * This could result in a SecurityException.
  228. *
  229. * @param port local port to use
  230. * @param laddr local address to bind
  231. *
  232. * @exception SocketException if the socket could not be opened,
  233. * or the socket could not bind to the specified local port.
  234. * @exception SecurityException if a security manager exists and its
  235. * <code>checkListen</code> method doesn't allow the operation.
  236. *
  237. * @see SecurityManager#checkListen
  238. * @since JDK1.1
  239. */
  240. public DatagramSocket(int port, InetAddress laddr) throws SocketException {
  241. this(new InetSocketAddress(laddr, port));
  242. }
  243. private void checkOldImpl() {
  244. if (impl == null)
  245. return;
  246. // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use
  247. // getDeclaredMethod, therefore we need permission to access the member
  248. try {
  249. AccessController.doPrivileged(new PrivilegedExceptionAction() {
  250. public Object run() throws NoSuchMethodException {
  251. Class[] cl = new Class[1];
  252. cl[0] = DatagramPacket.class;
  253. impl.getClass().getDeclaredMethod("peekData", cl);
  254. return null;
  255. }
  256. });
  257. } catch (java.security.PrivilegedActionException e) {
  258. oldImpl = true;
  259. }
  260. }
  261. static Class implClass = null;
  262. void createImpl() throws SocketException {
  263. if (impl == null) {
  264. if (factory != null) {
  265. impl = factory.createDatagramSocketImpl();
  266. checkOldImpl();
  267. } else {
  268. if (implClass == null) {
  269. String prefix = null;
  270. try {
  271. prefix = (String) AccessController.doPrivileged(
  272. new sun.security.action.GetPropertyAction("impl.prefix", "Plain"));
  273. implClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
  274. } catch (Exception e) {
  275. System.err.println("Can't find class: java.net." +
  276. prefix +
  277. "DatagramSocketImpl: check impl.prefix property");
  278. }
  279. if (implClass == null)
  280. implClass = java.net.PlainDatagramSocketImpl.class;
  281. }
  282. try {
  283. impl = (DatagramSocketImpl) implClass.newInstance();
  284. } catch (Exception e) {
  285. throw new SocketException("can't instantiate DatagramSocketImpl");
  286. }
  287. // No need to do a checkOldImpl() here, we know it's an up to date
  288. // SocketImpl!
  289. if (!(impl instanceof java.net.PlainDatagramSocketImpl))
  290. checkOldImpl();
  291. }
  292. }
  293. // creates a udp socket
  294. impl.create();
  295. created = true;
  296. }
  297. /**
  298. * Get the <code>DatagramSocketImpl</code> attached to this socket,
  299. * creating it if necessary.
  300. *
  301. * @return the <code>DatagramSocketImpl</code> attached to that
  302. * DatagramSocket
  303. * @throws SocketException if creation fails.
  304. * @since 1.4
  305. */
  306. DatagramSocketImpl getImpl() throws SocketException {
  307. if (!created)
  308. createImpl();
  309. return impl;
  310. }
  311. /**
  312. * Binds this DatagramSocket to a specific address & port.
  313. * <p>
  314. * If the address is <code>null</code>, then the system will pick up
  315. * an ephemeral port and a valid local address to bind the socket.
  316. *<p>
  317. * @param addr The address & port to bind to.
  318. * @throws SocketException if any error happens during the bind, or if the
  319. * socket is already bound.
  320. * @throws SecurityException if a security manager exists and its
  321. * <code>checkListen</code> method doesn't allow the operation.
  322. * @throws IllegalArgumentException if addr is a SocketAddress subclass
  323. * not supported by this socket.
  324. * @since 1.4
  325. */
  326. public synchronized void bind(SocketAddress addr) throws SocketException {
  327. if (isClosed())
  328. throw new SocketException("Socket is closed");
  329. if (isBound())
  330. throw new SocketException("already bound");
  331. if (addr == null)
  332. addr = new InetSocketAddress(0);
  333. if (!(addr instanceof InetSocketAddress))
  334. throw new IllegalArgumentException("Unsupported address type!");
  335. InetSocketAddress epoint = (InetSocketAddress) addr;
  336. if (epoint.isUnresolved())
  337. throw new SocketException("Unresolved address");
  338. SecurityManager sec = System.getSecurityManager();
  339. if (sec != null) {
  340. sec.checkListen(epoint.getPort());
  341. }
  342. try {
  343. getImpl().bind(epoint.getPort(),
  344. epoint.getAddress());
  345. } catch (SocketException e) {
  346. getImpl().close();
  347. throw e;
  348. }
  349. bound = true;
  350. }
  351. /**
  352. * Connects the socket to a remote address for this socket. When a
  353. * socket is connected to a remote address, packets may only be
  354. * sent to or received from that address. By default a datagram
  355. * socket is not connected.
  356. *
  357. * <p>If the remote destination to which the socket is connected does not
  358. * exist, or is otherwise unreachable, and if an ICMP destination unreachable
  359. * packet has been received for that address, then a subsequent call to
  360. * send or receive may throw a PortUnreachableException. Note, there is no
  361. * guarantee that the exception will be thrown.
  362. *
  363. * <p>A caller's permission to send and receive datagrams to a
  364. * given host and port are checked at connect time. When a socket
  365. * is connected, receive and send <b>will not
  366. * perform any security checks</b> on incoming and outgoing
  367. * packets, other than matching the packet's and the socket's
  368. * address and port. On a send operation, if the packet's address
  369. * is set and the packet's address and the socket's address do not
  370. * match, an IllegalArgumentException will be thrown. A socket
  371. * connected to a multicast address may only be used to send packets.
  372. *
  373. * @param address the remote address for the socket
  374. *
  375. * @param port the remote port for the socket.
  376. *
  377. * @exception IllegalArgumentException if the address is null,
  378. * or the port is out of range.
  379. *
  380. * @exception SecurityException if the caller is not allowed to
  381. * send datagrams to and receive datagrams from the address and port.
  382. *
  383. * @see #disconnect
  384. * @see #send
  385. * @see #receive
  386. */
  387. public void connect(InetAddress address, int port) {
  388. try {
  389. connectInternal(address, port);
  390. } catch (SocketException se) {
  391. throw new Error("connect failed", se);
  392. }
  393. }
  394. /**
  395. * Connects this socket to a remote socket address (IP address + port number).
  396. * <p>
  397. * @param addr The remote address.
  398. * @throws SocketException if the connect fails
  399. * @throws IllegalArgumentException if addr is null or addr is a SocketAddress
  400. * subclass not supported by this socket
  401. * @since 1.4
  402. * @see #connect
  403. */
  404. public void connect(SocketAddress addr) throws SocketException {
  405. if (addr == null)
  406. throw new IllegalArgumentException("Address can't be null");
  407. if (!(addr instanceof InetSocketAddress))
  408. throw new IllegalArgumentException("Unsupported address type");
  409. InetSocketAddress epoint = (InetSocketAddress) addr;
  410. if (epoint.isUnresolved())
  411. throw new SocketException("Unresolved address");
  412. connectInternal(epoint.getAddress(), epoint.getPort());
  413. }
  414. /**
  415. * Disconnects the socket. This does nothing if the socket is not
  416. * connected.
  417. *
  418. * @see #connect
  419. */
  420. public void disconnect() {
  421. synchronized (this) {
  422. if (isClosed())
  423. return;
  424. if (connectState == ST_CONNECTED) {
  425. impl.disconnect ();
  426. }
  427. connectedAddress = null;
  428. connectedPort = -1;
  429. connectState = ST_NOT_CONNECTED;
  430. }
  431. }
  432. /**
  433. * Returns the binding state of the socket.
  434. *
  435. * @return true if the socket succesfuly bound to an address
  436. * @since 1.4
  437. */
  438. public boolean isBound() {
  439. return bound;
  440. }
  441. /**
  442. * Returns the connection state of the socket.
  443. *
  444. * @return true if the socket succesfuly connected to a server
  445. * @since 1.4
  446. */
  447. public boolean isConnected() {
  448. return connectState != ST_NOT_CONNECTED;
  449. }
  450. /**
  451. * Returns the address to which this socket is connected. Returns null
  452. * if the socket is not connected.
  453. *
  454. * @return the address to which this socket is connected.
  455. */
  456. public InetAddress getInetAddress() {
  457. return connectedAddress;
  458. }
  459. /**
  460. * Returns the port for this socket. Returns -1 if the socket is not
  461. * connected.
  462. *
  463. * @return the port to which this socket is connected.
  464. */
  465. public int getPort() {
  466. return connectedPort;
  467. }
  468. /**
  469. * Returns the address of the endpoint this socket is connected to, or
  470. * <code>null</null> if it is unconnected.
  471. * @return a <code>SocketAddress</code> reprensenting the remote endpoint of this
  472. * socket, or <code>null</code> if it is not connected yet.
  473. * @see #getInetAddress()
  474. * @see #getPort()
  475. * @see #connect(SocketAddress)
  476. * @since 1.4
  477. */
  478. public SocketAddress getRemoteSocketAddress() {
  479. if (!isConnected())
  480. return null;
  481. return new InetSocketAddress(getInetAddress(), getPort());
  482. }
  483. /**
  484. * Returns the address of the endpoint this socket is bound to, or
  485. * <code>null</code> if it is not bound yet.
  486. *
  487. * @return a <code>SocketAddress</code> representing the local endpoint of this
  488. * socket, or <code>null</code> if it is not bound yet.
  489. * @see #getLocalAddress()
  490. * @see #getLocalPort()
  491. * @see #bind(SocketAddress)
  492. * @since 1.4
  493. */
  494. public SocketAddress getLocalSocketAddress() {
  495. if (!isBound())
  496. return null;
  497. return new InetSocketAddress(getLocalAddress(), getLocalPort());
  498. }
  499. /**
  500. * Sends a datagram packet from this socket. The
  501. * <code>DatagramPacket</code> includes information indicating the
  502. * data to be sent, its length, the IP address of the remote host,
  503. * and the port number on the remote host.
  504. *
  505. * <p>If there is a security manager, and the socket is not currently
  506. * connected to a remote address, this method first performs some
  507. * security checks. First, if <code>p.getAddress().isMulticastAddress()</code>
  508. * is true, this method calls the
  509. * security manager's <code>checkMulticast</code> method
  510. * with <code>p.getAddress()</code> as its argument.
  511. * If the evaluation of that expression is false,
  512. * this method instead calls the security manager's
  513. * <code>checkConnect</code> method with arguments
  514. * <code>p.getAddress().getHostAddress()</code> and
  515. * <code>p.getPort()</code>. Each call to a security manager method
  516. * could result in a SecurityException if the operation is not allowed.
  517. *
  518. * @param p the <code>DatagramPacket</code> to be sent.
  519. *
  520. * @exception IOException if an I/O error occurs.
  521. * @exception SecurityException if a security manager exists and its
  522. * <code>checkMulticast</code> or <code>checkConnect</code>
  523. * method doesn't allow the send.
  524. * @exception PortUnreachableException may be thrown if the socket is connected
  525. * to a currently unreachable destination. Note, there is no
  526. * guarantee that the exception will be thrown.
  527. * @exception java.nio.channels.IllegalBlockingModeException
  528. * if this socket has an associated channel,
  529. * and the channel is in non-blocking mode.
  530. *
  531. * @see java.net.DatagramPacket
  532. * @see SecurityManager#checkMulticast(InetAddress)
  533. * @see SecurityManager#checkConnect
  534. * @revised 1.4
  535. * @spec JSR-51
  536. */
  537. public void send(DatagramPacket p) throws IOException {
  538. InetAddress packetAddress = null;
  539. synchronized (p) {
  540. if (isClosed())
  541. throw new SocketException("Socket is closed");
  542. if (connectState == ST_NOT_CONNECTED) {
  543. // check the address is ok wiht the security manager on every send.
  544. SecurityManager security = System.getSecurityManager();
  545. // The reason you want to synchronize on datagram packet
  546. // is because you dont want an applet to change the address
  547. // while you are trying to send the packet for example
  548. // after the security check but before the send.
  549. if (security != null) {
  550. if (p.getAddress().isMulticastAddress()) {
  551. security.checkMulticast(p.getAddress());
  552. } else {
  553. security.checkConnect(p.getAddress().getHostAddress(),
  554. p.getPort());
  555. }
  556. }
  557. } else {
  558. // we're connected
  559. packetAddress = p.getAddress();
  560. if (packetAddress == null) {
  561. p.setAddress(connectedAddress);
  562. p.setPort(connectedPort);
  563. } else if ((!packetAddress.equals(connectedAddress)) ||
  564. p.getPort() != connectedPort) {
  565. throw new IllegalArgumentException("connected address " +
  566. "and packet address" +
  567. " differ");
  568. }
  569. }
  570. // Check whether the socket is bound
  571. if (!isBound())
  572. bind(new InetSocketAddress(0));
  573. // call the method to send
  574. getImpl().send(p);
  575. }
  576. }
  577. /**
  578. * Receives a datagram packet from this socket. When this method
  579. * returns, the <code>DatagramPacket</code>'s buffer is filled with
  580. * the data received. The datagram packet also contains the sender's
  581. * IP address, and the port number on the sender's machine.
  582. * <p>
  583. * This method blocks until a datagram is received. The
  584. * <code>length</code> field of the datagram packet object contains
  585. * the length of the received message. If the message is longer than
  586. * the packet's length, the message is truncated.
  587. * <p>
  588. * If there is a security manager, a packet cannot be received if the
  589. * security manager's <code>checkAccept</code> method
  590. * does not allow it.
  591. *
  592. * @param p the <code>DatagramPacket</code> into which to place
  593. * the incoming data.
  594. * @exception IOException if an I/O error occurs.
  595. * @exception SocketTimeoutException if setSoTimeout was previously called
  596. * and the timeout has expired.
  597. * @exception PortUnreachableException may be thrown if the socket is connected
  598. * to a currently unreachable destination. Note, there is no guarantee that the
  599. * exception will be thrown.
  600. * @exception java.nio.channels.IllegalBlockingModeException
  601. * if this socket has an associated channel,
  602. * and the channel is in non-blocking mode.
  603. * @see java.net.DatagramPacket
  604. * @see java.net.DatagramSocket
  605. * @revised 1.4
  606. * @spec JSR-51
  607. */
  608. public synchronized void receive(DatagramPacket p) throws IOException {
  609. synchronized (p) {
  610. if (!isBound())
  611. bind(new InetSocketAddress(0));
  612. if (connectState == ST_NOT_CONNECTED) {
  613. // check the address is ok with the security manager before every recv.
  614. SecurityManager security = System.getSecurityManager();
  615. if (security != null) {
  616. while(true) {
  617. String peekAd = null;
  618. int peekPort = 0;
  619. // peek at the packet to see who it is from.
  620. if (!oldImpl) {
  621. // We can use the new peekData() API
  622. DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
  623. peekPort = getImpl().peekData(peekPacket);
  624. peekAd = peekPacket.getAddress().getHostAddress();
  625. } else {
  626. InetAddress adr = new InetAddress();
  627. peekPort = getImpl().peek(adr);
  628. peekAd = adr.getHostAddress();
  629. }
  630. try {
  631. security.checkAccept(peekAd, peekPort);
  632. // security check succeeded - so now break
  633. // and recv the packet.
  634. break;
  635. } catch (SecurityException se) {
  636. // Throw away the offending packet by consuming
  637. // it in a tmp buffer.
  638. DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
  639. getImpl().receive(tmp);
  640. // silently discard the offending packet
  641. // and continue: unknown/malicious
  642. // entities on nets should not make
  643. // runtime throw security exception and
  644. // disrupt the applet by sending random
  645. // datagram packets.
  646. continue;
  647. }
  648. } // end of while
  649. }
  650. }
  651. if (connectState == ST_CONNECTED_NO_IMPL) {
  652. // We have to do the filtering the old fashioned way since
  653. // the native impl doesn't support connect or the connect
  654. // via the impl failed.
  655. boolean stop = false;
  656. while (!stop) {
  657. // peek at the packet to see who it is from.
  658. InetAddress peekAddress = new InetAddress();
  659. int peekPort = getImpl().peek(peekAddress);
  660. if ((!connectedAddress.equals(peekAddress)) ||
  661. (connectedPort != peekPort)) {
  662. // throw the packet away and silently continue
  663. DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
  664. getImpl().receive(tmp);
  665. } else {
  666. stop = true;
  667. }
  668. }
  669. }
  670. // If the security check succeeds, or the datagram is
  671. // connected then receive the packet
  672. getImpl().receive(p);
  673. }
  674. }
  675. /**
  676. * Gets the local address to which the socket is bound.
  677. *
  678. * <p>If there is a security manager, its
  679. * <code>checkConnect</code> method is first called
  680. * with the host address and <code>-1</code>
  681. * as its arguments to see if the operation is allowed.
  682. *
  683. * @see SecurityManager#checkConnect
  684. * @return the local address to which the socket is bound, or
  685. * an <code>InetAddress</code> representing any local
  686. * address if either the socket is not bound, or
  687. * the security manager <code>checkConnect</code>
  688. * method does not allow the operation
  689. * @since 1.1
  690. */
  691. public InetAddress getLocalAddress() {
  692. if (isClosed())
  693. return null;
  694. InetAddress in = null;
  695. try {
  696. in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
  697. if (in.isAnyLocalAddress()) {
  698. in = InetAddress.anyLocalAddress();
  699. }
  700. SecurityManager s = System.getSecurityManager();
  701. if (s != null) {
  702. s.checkConnect(in.getHostAddress(), -1);
  703. }
  704. } catch (Exception e) {
  705. in = InetAddress.anyLocalAddress(); // "0.0.0.0"
  706. }
  707. return in;
  708. }
  709. /**
  710. * Returns the port number on the local host to which this socket is bound.
  711. *
  712. * @return the port number on the local host to which this socket is bound.
  713. */
  714. public int getLocalPort() {
  715. if (isClosed())
  716. return -1;
  717. try {
  718. return getImpl().getLocalPort();
  719. } catch (Exception e) {
  720. return 0;
  721. }
  722. }
  723. /** Enable/disable SO_TIMEOUT with the specified timeout, in
  724. * milliseconds. With this option set to a non-zero timeout,
  725. * a call to receive() for this DatagramSocket
  726. * will block for only this amount of time. If the timeout expires,
  727. * a <B>java.net.SocketTimeoutException</B> is raised, though the
  728. * DatagramSocket is still valid. The option <B>must</B> be enabled
  729. * prior to entering the blocking operation to have effect. The
  730. * timeout must be > 0.
  731. * A timeout of zero is interpreted as an infinite timeout.
  732. *
  733. * @param timeout the specified timeout in milliseconds.
  734. * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
  735. * @since JDK1.1
  736. * @see #getSoTimeout()
  737. */
  738. public synchronized void setSoTimeout(int timeout) throws SocketException {
  739. if (isClosed())
  740. throw new SocketException("Socket is closed");
  741. getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  742. }
  743. /**
  744. * Retrive setting for SO_TIMEOUT. 0 returns implies that the
  745. * option is disabled (i.e., timeout of infinity).
  746. *
  747. * @return the setting for SO_TIMEOUT
  748. * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
  749. * @since JDK1.1
  750. * @see #setSoTimeout(int)
  751. */
  752. public synchronized int getSoTimeout() throws SocketException {
  753. if (isClosed())
  754. throw new SocketException("Socket is closed");
  755. if (getImpl() == null)
  756. return 0;
  757. Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
  758. /* extra type safety */
  759. if (o instanceof Integer) {
  760. return ((Integer) o).intValue();
  761. } else {
  762. return 0;
  763. }
  764. }
  765. /**
  766. * Sets the SO_SNDBUF option to the specified value for this
  767. * <tt>DatagramSocket</tt>. The SO_SNDBUF option is used by the
  768. * network implementation as a hint to size the underlying
  769. * network I/O buffers. The SO_SNDBUF setting may also be used
  770. * by the network implementation to determine the maximum size
  771. * of the packet that can be sent on this socket.
  772. * <p>
  773. * As SO_SNDBUF is a hint, applications that want to verify
  774. * what size the buffer is should call {@link #getSendBufferSize()}.
  775. * <p>
  776. * Increasing the buffer size may allow multiple outgoing packets
  777. * to be queued by the network implementation when the send rate
  778. * is high.
  779. * <p>
  780. * Note: If {@link #send()} is used to send a
  781. * <code>DatagramPacket</code> that is larger than the setting
  782. * of SO_SNDBUF then it is implementation specific if the
  783. * packet is sent or discarded.
  784. *
  785. * @param size the size to which to set the send buffer
  786. * size. This value must be greater than 0.
  787. *
  788. * @exception SocketException if there is an error
  789. * in the underlying protocol, such as an UDP error.
  790. * @exception IllegalArgumentException if the value is 0 or is
  791. * negative.
  792. * @see #getSendBufferSize()
  793. */
  794. public synchronized void setSendBufferSize(int size)
  795. throws SocketException{
  796. if (!(size > 0)) {
  797. throw new IllegalArgumentException("negative send size");
  798. }
  799. if (isClosed())
  800. throw new SocketException("Socket is closed");
  801. getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
  802. }
  803. /**
  804. * Get value of the SO_SNDBUF option for this <tt>DatagramSocket</tt>, that is the
  805. * buffer size used by the platform for output on this <tt>DatagramSocket</tt>.
  806. *
  807. * @return the value of the SO_SNDBUF option for this <tt>DatagramSocket</tt>
  808. * @exception SocketException if there is an error in
  809. * the underlying protocol, such as an UDP error.
  810. * @see #setSendBufferSize
  811. */
  812. public synchronized int getSendBufferSize() throws SocketException {
  813. if (isClosed())
  814. throw new SocketException("Socket is closed");
  815. int result = 0;
  816. Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
  817. if (o instanceof Integer) {
  818. result = ((Integer)o).intValue();
  819. }
  820. return result;
  821. }
  822. /**
  823. * Sets the SO_RCVBUF option to the specified value for this
  824. * <tt>DatagramSocket</tt>. The SO_RCVBUF option is used by the
  825. * the network implementation as a hint to size the underlying
  826. * network I/O buffers. The SO_RCVBUF setting may also be used
  827. * by the network implementation to determine the maximum size
  828. * of the packet that can be received on this socket.
  829. * <p>
  830. * Because SO_RCVBUF is a hint, applications that want to
  831. * verify what size the buffers were set to should call
  832. * {@link #getReceiveBufferSize()}.
  833. * <p>
  834. * Increasing SO_RCVBUF may allow the network implementation
  835. * to buffer multiple packets when packets arrive faster than
  836. * are being received using {@link #receive()}.
  837. * <p>
  838. * Note: It is implementation specific if a packet larger
  839. * than SO_RCVBUF can be received.
  840. *
  841. * @param size the size to which to set the receive buffer
  842. * size. This value must be greater than 0.
  843. *
  844. * @exception SocketException if there is an error in
  845. * the underlying protocol, such as an UDP error.
  846. * @exception IllegalArgumentException if the value is 0 or is
  847. * negative.
  848. * @see #getReceiveBufferSize()
  849. */
  850. public synchronized void setReceiveBufferSize(int size)
  851. throws SocketException{
  852. if (size <= 0) {
  853. throw new IllegalArgumentException("invalid receive size");
  854. }
  855. if (isClosed())
  856. throw new SocketException("Socket is closed");
  857. getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
  858. }
  859. /**
  860. * Get value of the SO_RCVBUF option for this <tt>DatagramSocket</tt>, that is the
  861. * buffer size used by the platform for input on this <tt>DatagramSocket</tt>.
  862. *
  863. * @return the value of the SO_RCVBUF option for this <tt>DatagramSocket</tt>
  864. * @exception SocketException if there is an error in the underlying protocol, such as an UDP error.
  865. * @see #setReceiveBufferSize(int)
  866. */
  867. public synchronized int getReceiveBufferSize()
  868. throws SocketException{
  869. if (isClosed())
  870. throw new SocketException("Socket is closed");
  871. int result = 0;
  872. Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
  873. if (o instanceof Integer) {
  874. result = ((Integer)o).intValue();
  875. }
  876. return result;
  877. }
  878. /**
  879. * Enable/disable the SO_REUSEADDR socket option.
  880. * <p>
  881. * For UDP sockets it may be necessary to bind more than one
  882. * socket to the same socket address. This is typically for the
  883. * purpose of receiving multicast packets
  884. * (See {@link #java.net.MulticastSocket}). The
  885. * <tt>SO_REUSEADDR</tt> socket option allows multiple
  886. * sockets to be bound to the same socket address if the
  887. * <tt>SO_REUSEADDR</tt> socket option is enabled prior
  888. * to binding the socket using {@link #bind(SocketAddress)}.
  889. * <p>
  890. * When a <tt>DatagramSocket</tt> is created the initial setting
  891. * of <tt>SO_REUSEADDR</tt> is disabled.
  892. * <p>
  893. * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
  894. * disabled after a socket is bound (See {@link #isBound()})
  895. * is not defined.
  896. *
  897. * @param on whether to enable or disable the
  898. * @exception SocketException if an error occurs enabling or
  899. * disabling the <tt>SO_RESUEADDR</tt> socket option,
  900. * or the socket is closed.
  901. * @since 1.4
  902. * @see #getReuseAddress()
  903. * @see #bind(SocketAddress)
  904. * @see #isBound()
  905. * @see #isClosed()
  906. */
  907. public synchronized void setReuseAddress(boolean on) throws SocketException {
  908. if (isClosed())
  909. throw new SocketException("Socket is closed");
  910. // Integer instead of Boolean for compatibility with older DatagramSocketImpl
  911. if (oldImpl)
  912. getImpl().setOption(SocketOptions.SO_REUSEADDR, new Integer(on?-1:0));
  913. else
  914. getImpl().setOption(SocketOptions.SO_REUSEADDR, new Boolean(on));
  915. }
  916. /**
  917. * Tests if SO_REUSEADDR is enabled.
  918. *
  919. * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
  920. * @exception SocketException if there is an error
  921. * in the underlying protocol, such as an UDP error.
  922. * @since 1.4
  923. * @see #setReuseAddress(boolean)
  924. */
  925. public synchronized boolean getReuseAddress() throws SocketException {
  926. if (isClosed())
  927. throw new SocketException("Socket is closed");
  928. Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
  929. return ((Boolean)o).booleanValue();
  930. }
  931. /**
  932. * Enable/disable SO_BROADCAST.
  933. * @param on whether or not to have broadcast turned on.
  934. * @exception SocketException if there is an error
  935. * in the underlying protocol, such as an UDP error.
  936. * @since 1.4
  937. * @see #getBroadcast()
  938. */
  939. public synchronized void setBroadcast(boolean on) throws SocketException {
  940. if (isClosed())
  941. throw new SocketException("Socket is closed");
  942. getImpl().setOption(SocketOptions.SO_BROADCAST, new Boolean(on));
  943. }
  944. /**
  945. * Tests if SO_BROADCAST is enabled.
  946. * @return a <code>boolean</code> indicating whether or not SO_BROADCAST is enabled.
  947. * @exception SocketException if there is an error
  948. * in the underlying protocol, such as an UDP error.
  949. * @since 1.4
  950. * @see #setBroadcast(boolean)
  951. */
  952. public synchronized boolean getBroadcast() throws SocketException {
  953. if (isClosed())
  954. throw new SocketException("Socket is closed");
  955. return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue();
  956. }
  957. /**
  958. * Sets traffic class or type-of-service octet in the IP
  959. * datagram header for datagrams sent from this DatagramSocket.
  960. * As the underlying network implementation may ignore this
  961. * value applications should consider it a hint.
  962. *
  963. * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
  964. * 255</code> or an IllegalArgumentException will be thrown.
  965. * <p>Notes:
  966. * <p> for Internet Protocol v4 the value consists of an octet
  967. * with precedence and TOS fields as detailed in RFC 1349. The
  968. * TOS field is bitset created by bitwise-or'ing values such
  969. * the following :-
  970. * <p>
  971. * <UL>
  972. * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
  973. * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
  974. * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
  975. * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
  976. * </UL>
  977. * The last low order bit is always ignored as this
  978. * corresponds to the MBZ (must be zero) bit.
  979. * <p>
  980. * Setting bits in the precedence field may result in a
  981. * SocketException indicating that the operation is not
  982. * permitted.
  983. * <p>
  984. * for Internet Protocol v6 <code>tc</code> is the value that
  985. * would be placed into the sin6_flowinfo field of the IP header.
  986. *
  987. * @param tc an <code>int</code> value for the bitset.
  988. * @throws SocketException if there is an error setting the
  989. * traffic class or type-of-service
  990. * @since 1.4
  991. * @see #getTrafficClass
  992. */
  993. public synchronized void setTrafficClass(int tc) throws SocketException {
  994. if (tc < 0 || tc > 255)
  995. throw new IllegalArgumentException("tc is not in range 0 -- 255");
  996. if (isClosed())
  997. throw new SocketException("Socket is closed");
  998. getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
  999. }
  1000. /**
  1001. * Gets traffic class or type-of-service in the IP datagram
  1002. * header for packets sent from this DatagramSocket.
  1003. * <p>
  1004. * As the underlying network implementation may ignore the
  1005. * traffic class or type-of-service set using {@link #setTrafficClass()}
  1006. * this method may return a different value than was previously
  1007. * set using the {@link #setTrafficClass()} method on this
  1008. * DatagramSocket.
  1009. *
  1010. * @return the traffic class or type-of-service already set
  1011. * @throws SocketException if there is an error obtaining the
  1012. * traffic class or type-of-service value.
  1013. * @since 1.4
  1014. * @see #setTrafficClass
  1015. */
  1016. public synchronized int getTrafficClass() throws SocketException {
  1017. if (isClosed())
  1018. throw new SocketException("Socket is closed");
  1019. return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue();
  1020. }
  1021. /**
  1022. * Closes this datagram socket.
  1023. * <p>
  1024. * Any thread currently blocked in {#link receive} upon this socket
  1025. * will throw a {@link SocketException}.
  1026. *
  1027. * <p> If this socket has an associated channel then the channel is closed
  1028. * as well.
  1029. *
  1030. * @revised 1.4
  1031. * @spec JSR-51
  1032. */
  1033. public void close() {
  1034. synchronized(closeLock) {
  1035. if (isClosed())
  1036. return;
  1037. impl.close();
  1038. closed = true;
  1039. }
  1040. }
  1041. /**
  1042. * Returns wether the socket is closed or not.
  1043. *
  1044. * @return true if the socket has been closed
  1045. * @since 1.4
  1046. */
  1047. public boolean isClosed() {
  1048. synchronized(closeLock) {
  1049. return closed;
  1050. }
  1051. }
  1052. /**
  1053. * Returns the unique {@link java.nio.channels.DatagramChannel} object
  1054. * associated with this datagram socket, if any.
  1055. *
  1056. * <p> A datagram socket will have a channel if, and only if, the channel
  1057. * itself was created via the {@link java.nio.channels.DatagramChannel#open
  1058. * DatagramChannel.open} method.
  1059. *
  1060. * @return the datagram channel associated with this datagram socket,
  1061. * or <tt>null</tt> if this socket was not created for a channel
  1062. *
  1063. * @since 1.4
  1064. * @spec JSR-51
  1065. */
  1066. public DatagramChannel getChannel() {
  1067. return null;
  1068. }
  1069. /**
  1070. * The factory for all datagram sockets.
  1071. */
  1072. static DatagramSocketImplFactory factory;
  1073. /**
  1074. * Sets the datagram socket implementation factory for the
  1075. * application. The factory can be specified only once.
  1076. * <p>
  1077. * When an application creates a new datagram socket, the socket
  1078. * implementation factory's <code>createDatagramSocketImpl</code> method is
  1079. * called to create the actual datagram socket implementation.
  1080. *
  1081. * <p>If there is a security manager, this method first calls
  1082. * the security manager's <code>checkSetFactory</code> method
  1083. * to ensure the operation is allowed.
  1084. * This could result in a SecurityException.
  1085. *
  1086. * @param fac the desired factory.
  1087. * @exception IOException if an I/O error occurs when setting the
  1088. * datagram socket factory.
  1089. * @exception SocketException if the factory is already defined.
  1090. * @exception SecurityException if a security manager exists and its
  1091. * <code>checkSetFactory</code> method doesn't allow the
  1092. operation.
  1093. * @see
  1094. java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
  1095. * @see SecurityManager#checkSetFactory
  1096. */
  1097. public static synchronized void
  1098. setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
  1099. throws IOException
  1100. {
  1101. if (factory != null) {
  1102. throw new SocketException("factory already defined");
  1103. }
  1104. SecurityManager security = System.getSecurityManager();
  1105. if (security != null) {
  1106. security.checkSetFactory();
  1107. }
  1108. factory = fac;
  1109. }
  1110. }