644 * guarantee that the exception will be thrown. |
644 * guarantee that the exception will be thrown. |
645 * @throws java.nio.channels.IllegalBlockingModeException |
645 * @throws java.nio.channels.IllegalBlockingModeException |
646 * if this socket has an associated channel, |
646 * if this socket has an associated channel, |
647 * and the channel is in non-blocking mode. |
647 * and the channel is in non-blocking mode. |
648 * @throws IllegalArgumentException if the socket is connected, |
648 * @throws IllegalArgumentException if the socket is connected, |
649 * and connected address and packet address differ. |
649 * and connected address and packet address differ, or |
|
650 * if the socket is not connected and the packet address |
|
651 * is not set. |
650 * |
652 * |
651 * @see java.net.DatagramPacket |
653 * @see java.net.DatagramPacket |
652 * @see SecurityManager#checkMulticast(InetAddress) |
654 * @see SecurityManager#checkMulticast(InetAddress) |
653 * @see SecurityManager#checkConnect |
655 * @see SecurityManager#checkConnect |
654 * @revised 1.4 |
656 * @revised 1.4 |
655 * @spec JSR-51 |
657 * @spec JSR-51 |
656 */ |
658 */ |
657 public void send(DatagramPacket p) throws IOException { |
659 public void send(DatagramPacket p) throws IOException { |
658 InetAddress packetAddress = null; |
|
659 synchronized (p) { |
660 synchronized (p) { |
660 if (isClosed()) |
661 if (isClosed()) |
661 throw new SocketException("Socket is closed"); |
662 throw new SocketException("Socket is closed"); |
662 checkAddress (p.getAddress(), "send"); |
663 InetAddress packetAddress = p.getAddress(); |
|
664 checkAddress (packetAddress, "send"); |
663 if (connectState == ST_NOT_CONNECTED) { |
665 if (connectState == ST_NOT_CONNECTED) { |
|
666 if (packetAddress == null) { |
|
667 throw new IllegalArgumentException("Address not set"); |
|
668 } |
664 // check the address is ok with the security manager on every send. |
669 // check the address is ok with the security manager on every send. |
665 SecurityManager security = System.getSecurityManager(); |
670 SecurityManager security = System.getSecurityManager(); |
666 |
671 |
667 // The reason you want to synchronize on datagram packet |
672 // The reason you want to synchronize on datagram packet |
668 // is because you don't want an applet to change the address |
673 // is because you don't want an applet to change the address |
669 // while you are trying to send the packet for example |
674 // while you are trying to send the packet for example |
670 // after the security check but before the send. |
675 // after the security check but before the send. |
671 if (security != null) { |
676 if (security != null) { |
672 if (p.getAddress().isMulticastAddress()) { |
677 if (packetAddress.isMulticastAddress()) { |
673 security.checkMulticast(p.getAddress()); |
678 security.checkMulticast(packetAddress); |
674 } else { |
679 } else { |
675 security.checkConnect(p.getAddress().getHostAddress(), |
680 security.checkConnect(packetAddress.getHostAddress(), |
676 p.getPort()); |
681 p.getPort()); |
677 } |
682 } |
678 } |
683 } |
679 } else { |
684 } else { |
680 // we're connected |
685 // we're connected |
681 packetAddress = p.getAddress(); |
|
682 if (packetAddress == null) { |
686 if (packetAddress == null) { |
683 p.setAddress(connectedAddress); |
687 p.setAddress(connectedAddress); |
684 p.setPort(connectedPort); |
688 p.setPort(connectedPort); |
685 } else if ((!packetAddress.equals(connectedAddress)) || |
689 } else if ((!packetAddress.equals(connectedAddress)) || |
686 p.getPort() != connectedPort) { |
690 p.getPort() != connectedPort) { |