PageRenderTime 49ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/jdk/src/share/classes/java/net/DatagramSocket.java

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