151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 38b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.net; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.DatagramChannel; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedExceptionAction; 34f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebskiimport android.system.ErrnoException; 35f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebskiimport libcore.io.Libcore; 36f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebskiimport static android.system.OsConstants.*; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This class represents a socket for sending and receiving datagram packets. 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>A datagram socket is the sending or receiving point for a packet 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * delivery service. Each packet sent or received on a datagram socket 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is individually addressed and routed. Multiple packets sent from 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * one machine to another may be routed differently, and may arrive in 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * any order. 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Where possible, a newly constructed {@code DatagramSocket} has the 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link SocketOptions#SO_BROADCAST SO_BROADCAST} socket option enabled so as 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to allow the transmission of broadcast datagrams. In order to receive 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * broadcast packets a DatagramSocket should be bound to the wildcard address. 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * In some implementations, broadcast packets may also be received when 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a DatagramSocket is bound to a more specific address. 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Example: 553a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramSocket s = new DatagramSocket(null); 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * s.bind(new InetSocketAddress(8888)); 583a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * } 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Which is equivalent to: 603a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramSocket s = new DatagramSocket(8888); 623a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * } 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Both cases will create a DatagramSocket able to receive broadcasts on 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * UDP port 8888. 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Pavani Diwanji 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.DatagramPacket 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.nio.channels.DatagramChannel 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.0 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass DatagramSocket implements java.io.Closeable { 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Various states of this socket. 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean created = false; 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean bound = false; 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private boolean closed = false; 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Object closeLock = new Object(); 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The implementation of this DatagramSocket. 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DatagramSocketImpl impl; 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Are we using an older DatagramSocketImpl? 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean oldImpl = false; 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 916031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong /** 926031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong * Set when a socket is ST_CONNECTED until we are certain 936031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong * that any packets which might have been received prior 946031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong * to calling connect() but not read by the application 956031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong * have been read. During this time we check the source 966031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong * address of all packets received to be sure they are from 976031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong * the connected destination. Other packets are read but 986031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong * silently dropped. 996031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong */ 1006031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong private boolean explicitFilter = false; 1016031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong private int bytesLeftToFilter; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Connection state: 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ST_NOT_CONNECTED = socket not connected 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ST_CONNECTED = socket connected 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ST_CONNECTED_NO_IMPL = socket connected but not at impl level 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final int ST_NOT_CONNECTED = 0; 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final int ST_CONNECTED = 1; 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static final int ST_CONNECTED_NO_IMPL = 2; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int connectState = ST_NOT_CONNECTED; 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Connected address & port 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress connectedAddress = null; 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int connectedPort = -1; 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1206975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // BEGIN Android-changed 1213ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak private SocketException pendingConnectException; 1226975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // END Android-changed 1233ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Connects this socket to a remote socket address (IP address + port number). 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Binds socket if not already bound. 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 1283a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @param address The remote address. 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param port The remote port 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException if binding the socket fails. 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private synchronized void connectInternal(InetAddress address, int port) throws SocketException { 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (port < 0 || port > 0xFFFF) { 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("connect: " + port); 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (address == null) { 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("connect: null address"); 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkAddress (address, "connect"); 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager security = System.getSecurityManager(); 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (security != null) { 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (address.isMulticastAddress()) { 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkMulticast(address); 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkConnect(address.getHostAddress(), port); 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkAccept(address.getHostAddress(), port); 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isBound()) 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bind(new InetSocketAddress(0)); 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 155979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // Android-changed: This section now throws any SocketException generated by connect() 156979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // to enable it to be recorded as the pendingConnectException. It has been enclosed in a 157979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // try-finally to ensure connectedAddress and connectedPort are set when the exception 158979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // is thrown. 159979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller try { 160979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // old impls do not support connect/disconnect 161979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // Android-changed: Added special handling for AbstractPlainDatagramSocketImpl in 162979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // the condition below. 163979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl && 164979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) { 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski connectState = ST_CONNECTED_NO_IMPL; 166979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller } else { 167979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller try { 168979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller getImpl().connect(address, port); 169979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller 170979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // socket is now connected by the impl 171979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller connectState = ST_CONNECTED; 172979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller 173979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // Do we need to filter some packets? 174979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller int avail = getImpl().dataAvailable(); 175979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller if (avail == -1) { 176979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller throw new SocketException(); 177979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller } 178979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller explicitFilter = avail > 0; 179979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller if (explicitFilter) { 180979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller bytesLeftToFilter = getReceiveBufferSize(); 181979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller } 182979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller } catch (SocketException se) { 183979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // connection will be emulated by DatagramSocket 184979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller connectState = ST_CONNECTED_NO_IMPL; 185979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller // Android-changed: Propagate the SocketException so connect() can store it. 186979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller throw se; 187979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller } 188979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller } 189979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller } finally { 190979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller connectedAddress = address; 191979fbd7f58c33df7534cbc10a31cfc6aea85aac2Neil Fuller connectedPort = port; 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a datagram socket and binds it to any available port 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on the local host machine. The socket will be bound to the 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link InetAddress#isAnyLocalAddress wildcard} address, 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an IP address chosen by the kernel. 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager, 2033a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * its {@code checkListen} method is first called 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with 0 as its argument to ensure the operation is allowed. 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This could result in a SecurityException. 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if the socket could not be opened, 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or the socket could not bind to the specified local port. 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 2103a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkListen} method doesn't allow the operation. 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkListen 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramSocket() throws SocketException { 215dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong this(new InetSocketAddress(0)); 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates an unbound datagram socket with the specified 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramSocketImpl. 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param impl an instance of a <B>DatagramSocketImpl</B> 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the subclass wishes to use on the DatagramSocket. 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected DatagramSocket(DatagramSocketImpl impl) { 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (impl == null) 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.impl = impl; 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkOldImpl(); 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a datagram socket, bound to the specified local 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * socket address. 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 2373a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * If, if the address is {@code null}, creates an unbound socket. 2383a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager, 2403a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * its {@code checkListen} method is first called 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the port from the socket address 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as its argument to ensure the operation is allowed. 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This could result in a SecurityException. 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2453a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @param bindaddr local socket address to bind, or {@code null} 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for an unbound socket. 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if the socket could not be opened, 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or the socket could not bind to the specified local port. 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 2513a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkListen} method doesn't allow the operation. 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkListen 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramSocket(SocketAddress bindaddr) throws SocketException { 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // create a datagram socket. 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski createImpl(); 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (bindaddr != null) { 260dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong try { 261dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong bind(bindaddr); 262dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong } finally { 263dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong if (!isBound()) 264dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong close(); 265dbaa8e737b0e5ecff9f7b95b4dbc7e217fc493eeYi Kong } 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructs a datagram socket and binds it to the specified port 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on the local host machine. The socket will be bound to the 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link InetAddress#isAnyLocalAddress wildcard} address, 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an IP address chosen by the kernel. 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager, 2763a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * its {@code checkListen} method is first called 2773a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * with the {@code port} argument 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as its argument to ensure the operation is allowed. 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This could result in a SecurityException. 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param port port to use. 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if the socket could not be opened, 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or the socket could not bind to the specified local port. 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 2853a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkListen} method doesn't allow the operation. 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkListen 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramSocket(int port) throws SocketException { 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(port, null); 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a datagram socket, bound to the specified local 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * address. The local port must be between 0 and 65535 inclusive. 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the IP address is 0.0.0.0, the socket will be bound to the 29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link InetAddress#isAnyLocalAddress wildcard} address, 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an IP address chosen by the kernel. 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager, 3013a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * its {@code checkListen} method is first called 3023a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * with the {@code port} argument 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as its argument to ensure the operation is allowed. 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This could result in a SecurityException. 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param port local port to use 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param laddr local address to bind 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if the socket could not be opened, 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or the socket could not bind to the specified local port. 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 3123a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkListen} method doesn't allow the operation. 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkListen 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramSocket(int port, InetAddress laddr) throws SocketException { 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(new InetSocketAddress(laddr, port)); 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void checkOldImpl() { 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (impl == null) 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // getDeclaredMethod, therefore we need permission to access the member 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski AccessController.doPrivileged( 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new PrivilegedExceptionAction<Void>() { 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public Void run() throws NoSuchMethodException { 3303a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong Class<?>[] cl = new Class<?>[1]; 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl[0] = DatagramPacket.class; 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski impl.getClass().getDeclaredMethod("peekData", cl); 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski }); 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (java.security.PrivilegedActionException e) { 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski oldImpl = true; 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3413a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong static Class<?> implClass = null; 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void createImpl() throws SocketException { 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (impl == null) { 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (factory != null) { 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski impl = factory.createDatagramSocketImpl(); 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkOldImpl(); 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isMulticast = (this instanceof MulticastSocket) ? true : false; 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(isMulticast); 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkOldImpl(); 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // creates a udp socket 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski impl.create(); 357e573e88e89daf5efb323719c54117c5a423eb245Yi Kong impl.setDatagramSocket(this); 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski created = true; 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 3623a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * Get the {@code DatagramSocketImpl} attached to this socket, 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * creating it if necessary. 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 3653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @return the {@code DatagramSocketImpl} attached to that 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramSocket 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException if creation fails. 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DatagramSocketImpl getImpl() throws SocketException { 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!created) 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski createImpl(); 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return impl; 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 3773a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * Binds this DatagramSocket to a specific address and port. 37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 3793a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * If the address is {@code null}, then the system will pick up 38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * an ephemeral port and a valid local address to bind the socket. 38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *<p> 3823a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @param addr The address and port to bind to. 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException if any error happens during the bind, or if the 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * socket is already bound. 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException if a security manager exists and its 3863a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkListen} method doesn't allow the operation. 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException if addr is a SocketAddress subclass 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not supported by this socket. 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void bind(SocketAddress addr) throws SocketException { 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isBound()) 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("already bound"); 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (addr == null) 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addr = new InetSocketAddress(0); 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(addr instanceof InetSocketAddress)) 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Unsupported address type!"); 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress epoint = (InetSocketAddress) addr; 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (epoint.isUnresolved()) 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Unresolved address"); 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress iaddr = epoint.getAddress(); 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int port = epoint.getPort(); 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkAddress(iaddr, "bind"); 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager sec = System.getSecurityManager(); 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (sec != null) { 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski sec.checkListen(port); 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().bind(port, iaddr); 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (SocketException e) { 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().close(); 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw e; 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bound = true; 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void checkAddress (InetAddress addr, String op) { 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (addr == null) { 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) { 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException(op + ": invalid address type"); 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Connects the socket to a remote address for this socket. When a 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * socket is connected to a remote address, packets may only be 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * sent to or received from that address. By default a datagram 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * socket is not connected. 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If the remote destination to which the socket is connected does not 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exist, or is otherwise unreachable, and if an ICMP destination unreachable 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * packet has been received for that address, then a subsequent call to 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * send or receive may throw a PortUnreachableException. Note, there is no 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * guarantee that the exception will be thrown. 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> If a security manager has been installed then it is invoked to check 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * access to the remote address. Specifically, if the given {@code address} 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is a {@link InetAddress#isMulticastAddress multicast address}, 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the security manager's {@link 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.SecurityManager#checkMulticast(InetAddress) 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * checkMulticast} method is invoked with the given {@code address}. 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Otherwise, the security manager's {@link 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.SecurityManager#checkConnect(String,int) checkConnect} 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are invoked, with the given {@code address} and {@code port}, to 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * verify that datagrams are permitted to be sent and received 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * respectively. 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> When a socket is connected, {@link #receive receive} and 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #send send} <b>will not perform any security checks</b> 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * on incoming and outgoing packets, other than matching the packet's 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the socket's address and port. On a send operation, if the 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * packet's address is set and the packet's address and the socket's 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * address do not match, an {@code IllegalArgumentException} will be 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * thrown. A socket connected to a multicast address may only be used 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to send packets. 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param address the remote address for the socket 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param port the remote port for the socket. 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if the address is null, or the port is out of range. 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if a security manager has been installed and it does 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not permit access to the given remote address 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #disconnect 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void connect(InetAddress address, int port) { 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski connectInternal(address, port); 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (SocketException se) { 4796975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // BEGIN Android-changed 4803ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak //throw new Error("connect failed", se); 4813ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak // TODO: or just use SneakyThrow? There's a clear API bug here. 482232065a74a6bfb1dcb7b31359108359932a3d737Przemyslaw Szczepaniak pendingConnectException = se; 4836975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // END Android-changed 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Connects this socket to a remote socket address (IP address + port number). 48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method 49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)} 49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * with the the given socket addresses IP address and port number. 49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param addr The remote address. 49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException 49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if the connect fails 49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IllegalArgumentException 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if {@code addr} is {@code null}, or {@code addr} is a SocketAddress 50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * subclass not supported by this socket 50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SecurityException 50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if a security manager has been installed and it does 50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not permit access to the given remote address 50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void connect(SocketAddress addr) throws SocketException { 51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (addr == null) 51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Address can't be null"); 51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(addr instanceof InetSocketAddress)) 51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Unsupported address type"); 51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetSocketAddress epoint = (InetSocketAddress) addr; 51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (epoint.isUnresolved()) 51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Unresolved address"); 51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski connectInternal(epoint.getAddress(), epoint.getPort()); 51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Disconnects the socket. If the socket is closed or not connected, 52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * then this method has no effect. 52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #connect 52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void disconnect() { 52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (this) { 52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (connectState == ST_CONNECTED) { 53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski impl.disconnect (); 53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski connectedAddress = null; 53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski connectedPort = -1; 53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski connectState = ST_NOT_CONNECTED; 5366031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong explicitFilter = false; 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the binding state of the socket. 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the socket was bound prior to being {@link #close closed}, 5443a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * then this method will continue to return {@code true} 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * after the socket is closed. 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if the socket successfully bound to an address 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isBound() { 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return bound; 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the connection state of the socket. 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the socket was connected prior to being {@link #close closed}, 5583a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * then this method will continue to return {@code true} 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * after the socket is closed. 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if the socket successfully connected to a server 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isConnected() { 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return connectState != ST_NOT_CONNECTED; 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the address to which this socket is connected. Returns 5703a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code null} if the socket is not connected. 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the socket was connected prior to being {@link #close closed}, 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * then this method will continue to return the connected address 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * after the socket is closed. 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the address to which this socket is connected. 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public InetAddress getInetAddress() { 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return connectedAddress; 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the port number to which this socket is connected. 5843a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * Returns {@code -1} if the socket is not connected. 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the socket was connected prior to being {@link #close closed}, 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * then this method will continue to return the connected port number 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * after the socket is closed. 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the port number to which this socket is connected. 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getPort() { 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return connectedPort; 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the address of the endpoint this socket is connected to, or 5983a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code null} if it is unconnected. 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the socket was connected prior to being {@link #close closed}, 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * then this method will continue to return the connected address 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * after the socket is closed. 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6043a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @return a {@code SocketAddress} representing the remote 6053a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * endpoint of this socket, or {@code null} if it is 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not connected yet. 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getInetAddress() 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getPort() 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #connect(SocketAddress) 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress getRemoteSocketAddress() { 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isConnected()) 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new InetSocketAddress(getInetAddress(), getPort()); 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the address of the endpoint this socket is bound to. 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6213a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @return a {@code SocketAddress} representing the local endpoint of this 6223a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * socket, or {@code null} if it is closed or not bound yet. 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getLocalAddress() 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getLocalPort() 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #bind(SocketAddress) 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SocketAddress getLocalSocketAddress() { 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isBound()) 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new InetSocketAddress(getLocalAddress(), getLocalPort()); 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sends a datagram packet from this socket. The 6393a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code DatagramPacket} includes information indicating the 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * data to be sent, its length, the IP address of the remote host, 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the port number on the remote host. 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager, and the socket is not currently 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * connected to a remote address, this method first performs some 6453a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * security checks. First, if {@code p.getAddress().isMulticastAddress()} 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is true, this method calls the 6473a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * security manager's {@code checkMulticast} method 6483a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * with {@code p.getAddress()} as its argument. 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the evaluation of that expression is false, 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this method instead calls the security manager's 6513a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkConnect} method with arguments 6523a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code p.getAddress().getHostAddress()} and 6533a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code p.getPort()}. Each call to a security manager method 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * could result in a SecurityException if the operation is not allowed. 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 6563a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @param p the {@code DatagramPacket} to be sent. 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 6603a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkMulticast} or {@code checkConnect} 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method doesn't allow the send. 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception PortUnreachableException may be thrown if the socket is connected 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to a currently unreachable destination. Note, there is no 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * guarantee that the exception will be thrown. 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception java.nio.channels.IllegalBlockingModeException 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if this socket has an associated channel, 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the channel is in non-blocking mode. 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the socket is connected, 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and connected address and packet address differ. 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.DatagramPacket 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkMulticast(InetAddress) 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkConnect 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @revised 1.4 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @spec JSR-51 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void send(DatagramPacket p) throws IOException { 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress packetAddress = null; 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (p) { 6806975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // BEGIN Android-changed 6813a50b32e2abec315948e1947450cd0f7c0c82b2dHans MÃ¥nsson if (pendingConnectException != null) { 6823a50b32e2abec315948e1947450cd0f7c0c82b2dHans MÃ¥nsson throw new SocketException("Pending connect failure", pendingConnectException); 6833a50b32e2abec315948e1947450cd0f7c0c82b2dHans MÃ¥nsson } 6846975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // END Android-changed 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkAddress (p.getAddress(), "send"); 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (connectState == ST_NOT_CONNECTED) { 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check the address is ok wiht the security manager on every send. 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager security = System.getSecurityManager(); 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The reason you want to synchronize on datagram packet 6933a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong // is because you don't want an applet to change the address 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // while you are trying to send the packet for example 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // after the security check but before the send. 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (security != null) { 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (p.getAddress().isMulticastAddress()) { 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkMulticast(p.getAddress()); 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkConnect(p.getAddress().getHostAddress(), 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p.getPort()); 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // we're connected 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski packetAddress = p.getAddress(); 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (packetAddress == null) { 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p.setAddress(connectedAddress); 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p.setPort(connectedPort); 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else if ((!packetAddress.equals(connectedAddress)) || 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p.getPort() != connectedPort) { 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("connected address " + 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "and packet address" + 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski " differ"); 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Check whether the socket is bound 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isBound()) 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bind(new InetSocketAddress(0)); 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // call the method to send 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().send(p); 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Receives a datagram packet from this socket. When this method 7273a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * returns, the {@code DatagramPacket}'s buffer is filled with 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the data received. The datagram packet also contains the sender's 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * IP address, and the port number on the sender's machine. 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This method blocks until a datagram is received. The 7323a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code length} field of the datagram packet object contains 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the length of the received message. If the message is longer than 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the packet's length, the message is truncated. 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If there is a security manager, a packet cannot be received if the 7373a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * security manager's {@code checkAccept} method 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * does not allow it. 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 7403a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @param p the {@code DatagramPacket} into which to place 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the incoming data. 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketTimeoutException if setSoTimeout was previously called 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the timeout has expired. 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception PortUnreachableException may be thrown if the socket is connected 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to a currently unreachable destination. Note, there is no guarantee that the 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exception will be thrown. 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception java.nio.channels.IllegalBlockingModeException 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if this socket has an associated channel, 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and the channel is in non-blocking mode. 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.DatagramPacket 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.net.DatagramSocket 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @revised 1.4 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @spec JSR-51 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void receive(DatagramPacket p) throws IOException { 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (p) { 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isBound()) 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bind(new InetSocketAddress(0)); 7603ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak 7616975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // BEGIN Android-changed 7623ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak if (pendingConnectException != null) { 7633ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak throw new SocketException("Pending connect failure", pendingConnectException); 7643ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak } 7656975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // END Android-changed 7663ead9ed960dd17b53e2a7ce1edeccd572ac61ddfPrzemyslaw Szczepaniak 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (connectState == ST_NOT_CONNECTED) { 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // check the address is ok with the security manager before every recv. 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager security = System.getSecurityManager(); 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (security != null) { 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while(true) { 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String peekAd = null; 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int peekPort = 0; 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // peek at the packet to see who it is from. 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!oldImpl) { 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // We can use the new peekData() API 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1); 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekPort = getImpl().peekData(peekPacket); 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekAd = peekPacket.getAddress().getHostAddress(); 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress adr = new InetAddress(); 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekPort = getImpl().peek(adr); 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekAd = adr.getHostAddress(); 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkAccept(peekAd, peekPort); 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // security check succeeded - so now break 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // and recv the packet. 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (SecurityException se) { 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Throw away the offending packet by consuming 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // it in a tmp buffer. 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DatagramPacket tmp = new DatagramPacket(new byte[1], 1); 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().receive(tmp); 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // silently discard the offending packet 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // and continue: unknown/malicious 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // entities on nets should not make 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // runtime throw security exception and 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // disrupt the applet by sending random 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // datagram packets. 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski continue; 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } // end of while 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8078b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong DatagramPacket tmp = null; 8086031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) { 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // We have to do the filtering the old fashioned way since 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the native impl doesn't support connect or the connect 8116031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong // via the impl failed, or .. "explicitFilter" may be set when 8126031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong // a socket is connected via the impl, for a period of time 8136031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong // when packets from other sources might be queued on socket. 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean stop = false; 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (!stop) { 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress peekAddress = null; 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int peekPort = -1; 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // peek at the packet to see who it is from. 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!oldImpl) { 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // We can use the new peekData() API 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1); 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekPort = getImpl().peekData(peekPacket); 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekAddress = peekPacket.getAddress(); 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // this api only works for IPv4 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekAddress = new InetAddress(); 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski peekPort = getImpl().peek(peekAddress); 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((!connectedAddress.equals(peekAddress)) || 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski (connectedPort != peekPort)) { 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // throw the packet away and silently continue 8328b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong tmp = new DatagramPacket( 8336031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong new byte[1024], 1024); 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().receive(tmp); 8356031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong if (explicitFilter) { 8368b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong if (checkFiltering(tmp)) { 8378b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong stop = true; 8388b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong } 8396031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong } 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski stop = true; 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If the security check succeeds, or the datagram is 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // connected then receive the packet 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().receive(p); 8488b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong if (explicitFilter && tmp == null) { 8498b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong // packet was not filtered, account for it here 8508b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong checkFiltering(p); 8516031a510d88327487d4a22bdfef0c6ba17a7b2a6Yi Kong } 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8558b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong private boolean checkFiltering(DatagramPacket p) throws SocketException { 8568b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong bytesLeftToFilter -= p.getLength(); 8578b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) { 8588b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong explicitFilter = false; 8598b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong return true; 8608b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong } 8618b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong return false; 8628b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong } 8638b9413f7171bd5193be546cd3a2bc9672bcf725dYi Kong 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets the local address to which the socket is bound. 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager, its 8683a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkConnect} method is first called 8693a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * with the host address and {@code -1} 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as its arguments to see if the operation is allowed. 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkConnect 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the local address to which the socket is bound, 8743a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code null} if the socket is closed, or 8753a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * an {@code InetAddress} representing 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link InetAddress#isAnyLocalAddress wildcard} 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * address if either the socket is not bound, or 8783a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * the security manager {@code checkConnect} 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method does not allow the operation 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.1 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public InetAddress getLocalAddress() { 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski InetAddress in = null; 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR); 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (in.isAnyLocalAddress()) { 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in = InetAddress.anyLocalAddress(); 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager s = System.getSecurityManager(); 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (s != null) { 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s.checkConnect(in.getHostAddress(), -1); 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski in = InetAddress.anyLocalAddress(); // "0.0.0.0" 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return in; 89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the port number on the local host to which this socket 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is bound. 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the port number on the local host to which this socket is bound, 9063a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong {@code -1} if the socket is closed, or 9073a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong {@code 0} if it is not bound yet. 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int getLocalPort() { 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return getImpl().getLocalPort(); 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Exception e) { 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** Enable/disable SO_TIMEOUT with the specified timeout, in 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * milliseconds. With this option set to a non-zero timeout, 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a call to receive() for this DatagramSocket 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will block for only this amount of time. If the timeout expires, 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a <B>java.net.SocketTimeoutException</B> is raised, though the 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramSocket is still valid. The option <B>must</B> be enabled 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * prior to entering the blocking operation to have effect. The 9263a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * timeout must be {@code > 0}. 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A timeout of zero is interpreted as an infinite timeout. 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param timeout the specified timeout in milliseconds. 93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException if there is an error in the underlying protocol, such as an UDP error. 93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1 93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getSoTimeout() 93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void setSoTimeout(int timeout) throws SocketException { 93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout)); 93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Retrieve setting for SO_TIMEOUT. 0 returns implies that the 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * option is disabled (i.e., timeout of infinity). 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the setting for SO_TIMEOUT 94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException if there is an error in the underlying protocol, such as an UDP error. 94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1 94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #setSoTimeout(int) 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized int getSoTimeout() throws SocketException { 95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (getImpl() == null) 95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT); 95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /* extra type safety */ 95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (o instanceof Integer) { 95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((Integer) o).intValue(); 95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 96251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets the SO_SNDBUF option to the specified value for this 9653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code DatagramSocket}. The SO_SNDBUF option is used by the 96651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * network implementation as a hint to size the underlying 96751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * network I/O buffers. The SO_SNDBUF setting may also be used 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the network implementation to determine the maximum size 96951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the packet that can be sent on this socket. 97051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * As SO_SNDBUF is a hint, applications that want to verify 97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * what size the buffer is should call {@link #getSendBufferSize()}. 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Increasing the buffer size may allow multiple outgoing packets 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to be queued by the network implementation when the send rate 97651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is high. 97751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note: If {@link #send(DatagramPacket)} is used to send a 9793a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code DatagramPacket} that is larger than the setting 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of SO_SNDBUF then it is implementation specific if the 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * packet is sent or discarded. 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param size the size to which to set the send buffer 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * size. This value must be greater than 0. 98551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if there is an error 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in the underlying protocol, such as an UDP error. 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the value is 0 or is 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * negative. 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getSendBufferSize() 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void setSendBufferSize(int size) 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws SocketException{ 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!(size > 0)) { 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("negative send size"); 99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size)); 100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10033a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * Get value of the SO_SNDBUF option for this {@code DatagramSocket}, that is the 10043a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * buffer size used by the platform for output on this {@code DatagramSocket}. 100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10063a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @return the value of the SO_SNDBUF option for this {@code DatagramSocket} 100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if there is an error in 100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the underlying protocol, such as an UDP error. 100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #setSendBufferSize 101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized int getSendBufferSize() throws SocketException { 101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int result = 0; 101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object o = getImpl().getOption(SocketOptions.SO_SNDBUF); 101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (o instanceof Integer) { 101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result = ((Integer)o).intValue(); 101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result; 102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets the SO_RCVBUF option to the specified value for this 10243a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code DatagramSocket}. The SO_RCVBUF option is used by the 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the network implementation as a hint to size the underlying 102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * network I/O buffers. The SO_RCVBUF setting may also be used 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by the network implementation to determine the maximum size 102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * of the packet that can be received on this socket. 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Because SO_RCVBUF is a hint, applications that want to 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * verify what size the buffers were set to should call 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * {@link #getReceiveBufferSize()}. 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Increasing SO_RCVBUF may allow the network implementation 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to buffer multiple packets when packets arrive faster than 103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are being received using {@link #receive(DatagramPacket)}. 103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note: It is implementation specific if a packet larger 103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * than SO_RCVBUF can be received. 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param size the size to which to set the receive buffer 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * size. This value must be greater than 0. 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if there is an error in 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the underlying protocol, such as an UDP error. 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IllegalArgumentException if the value is 0 or is 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * negative. 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getReceiveBufferSize() 104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void setReceiveBufferSize(int size) 105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws SocketException{ 105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (size <= 0) { 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("invalid receive size"); 105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size)); 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 10613a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * Get value of the SO_RCVBUF option for this {@code DatagramSocket}, that is the 10623a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * buffer size used by the platform for input on this {@code DatagramSocket}. 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10643a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @return the value of the SO_RCVBUF option for this {@code DatagramSocket} 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if there is an error in the underlying protocol, such as an UDP error. 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #setReceiveBufferSize(int) 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized int getReceiveBufferSize() 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws SocketException{ 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int result = 0; 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object o = getImpl().getOption(SocketOptions.SO_RCVBUF); 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (o instanceof Integer) { 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result = ((Integer)o).intValue(); 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result; 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Enable/disable the SO_REUSEADDR socket option. 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For UDP sockets it may be necessary to bind more than one 108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * socket to the same socket address. This is typically for the 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * purpose of receiving multicast packets 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (See {@link java.net.MulticastSocket}). The 10873a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code SO_REUSEADDR} socket option allows multiple 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * sockets to be bound to the same socket address if the 10893a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code SO_REUSEADDR} socket option is enabled prior 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to binding the socket using {@link #bind(SocketAddress)}. 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Note: This functionality is not supported by all existing platforms, 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * so it is implementation specific whether this option will be ignored 109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or not. However, if it is not supported then 10953a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@link #getReuseAddress()} will always return {@code false}. 109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 10973a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * When a {@code DatagramSocket} is created the initial setting 10983a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * of {@code SO_REUSEADDR} is disabled. 109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 11003a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * The behaviour when {@code SO_REUSEADDR} is enabled or 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * disabled after a socket is bound (See {@link #isBound()}) 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is not defined. 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param on whether to enable or disable the 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if an error occurs enabling or 11063a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * disabling the {@code SO_RESUEADDR} socket option, 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or the socket is closed. 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getReuseAddress() 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #bind(SocketAddress) 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #isBound() 111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #isClosed() 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void setReuseAddress(boolean on) throws SocketException { 111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Integer instead of Boolean for compatibility with older DatagramSocketImpl 111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (oldImpl) 111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().setOption(SocketOptions.SO_REUSEADDR, new Integer(on?-1:0)); 112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else 112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); 112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tests if SO_REUSEADDR is enabled. 112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11273a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @return a {@code boolean} indicating whether or not SO_REUSEADDR is enabled. 112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if there is an error 112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in the underlying protocol, such as an UDP error. 113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #setReuseAddress(boolean) 113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized boolean getReuseAddress() throws SocketException { 113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR); 113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((Boolean)o).booleanValue(); 113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Enable/disable SO_BROADCAST. 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Some operating systems may require that the Java virtual machine be 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * started with implementation specific privileges to enable this option or 114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * send broadcast datagrams. 114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param on 114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * whether or not to have broadcast turned on. 114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException 115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * if there is an error in the underlying protocol, such as an UDP 115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * error. 115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getBroadcast() 115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void setBroadcast(boolean on) throws SocketException { 115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on)); 116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Tests if SO_BROADCAST is enabled. 11653a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @return a {@code boolean} indicating whether or not SO_BROADCAST is enabled. 116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if there is an error 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * in the underlying protocol, such as an UDP error. 116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #setBroadcast(boolean) 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized boolean getBroadcast() throws SocketException { 117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue(); 117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets traffic class or type-of-service octet in the IP 117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * datagram header for datagrams sent from this DatagramSocket. 118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * As the underlying network implementation may ignore this 118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * value applications should consider it a hint. 118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 11833a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * <P> The tc <B>must</B> be in the range {@code 0 <= tc <= 11843a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * 255} or an IllegalArgumentException will be thrown. 118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>Notes: 118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>For Internet Protocol v4 the value consists of an 11873a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code integer}, the least significant 8 bits of which 118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * represent the value of the TOS octet in IP packets sent by 118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the socket. 119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * RFC 1349 defines the TOS values as follows: 11913a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * 119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <UL> 119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI> 119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI> 119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI> 119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI> 119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </UL> 119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The last low order bit is always ignored as this 119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * corresponds to the MBZ (must be zero) bit. 120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Setting bits in the precedence field may result in a 120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * SocketException indicating that the operation is not 120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * permitted. 120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 12053a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * for Internet Protocol v6 {@code tc} is the value that 120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * would be placed into the sin6_flowinfo field of the IP header. 120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 12083a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * @param tc an {@code int} value for the bitset. 120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException if there is an error setting the 121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * traffic class or type-of-service 121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #getTrafficClass 121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized void setTrafficClass(int tc) throws SocketException { 121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tc < 0 || tc > 255) 121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("tc is not in range 0 -- 255"); 121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 1220780a0e6392567eb5d1c3425043b092d29590976bYi Kong try { 1221780a0e6392567eb5d1c3425043b092d29590976bYi Kong getImpl().setOption(SocketOptions.IP_TOS, tc); 1222780a0e6392567eb5d1c3425043b092d29590976bYi Kong } catch (SocketException se) { 1223780a0e6392567eb5d1c3425043b092d29590976bYi Kong // not supported if socket already connected 1224780a0e6392567eb5d1c3425043b092d29590976bYi Kong // Solaris returns error in such cases 1225780a0e6392567eb5d1c3425043b092d29590976bYi Kong if(!isConnected()) 1226780a0e6392567eb5d1c3425043b092d29590976bYi Kong throw se; 1227780a0e6392567eb5d1c3425043b092d29590976bYi Kong } 122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Gets traffic class or type-of-service in the IP datagram 123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * header for packets sent from this DatagramSocket. 123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * As the underlying network implementation may ignore the 123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * traffic class or type-of-service set using {@link #setTrafficClass(int)} 123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this method may return a different value than was previously 123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * set using the {@link #setTrafficClass(int)} method on this 123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramSocket. 123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the traffic class or type-of-service already set 124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws SocketException if there is an error obtaining the 124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * traffic class or type-of-service value. 124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see #setTrafficClass(int) 124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized int getTrafficClass() throws SocketException { 124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("Socket is closed"); 124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue(); 125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Closes this datagram socket. 125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Any thread currently blocked in {@link #receive} upon this socket 125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * will throw a {@link SocketException}. 125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> If this socket has an associated channel then the channel is closed 125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as well. 126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @revised 1.4 126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @spec JSR-51 126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() { 126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(closeLock) { 126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isClosed()) 126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski impl.close(); 126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski closed = true; 127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns whether the socket is closed or not. 127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if the socket has been closed 127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isClosed() { 128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(closeLock) { 128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return closed; 128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the unique {@link java.nio.channels.DatagramChannel} object 128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with this datagram socket, if any. 128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> A datagram socket will have a channel if, and only if, the channel 129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * itself was created via the {@link java.nio.channels.DatagramChannel#open 129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DatagramChannel.open} method. 129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the datagram channel associated with this datagram socket, 12943a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * or {@code null} if this socket was not created for a channel 129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @spec JSR-51 129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public DatagramChannel getChannel() { 130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * User defined factory for all datagram sockets. 130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static DatagramSocketImplFactory factory; 130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sets the datagram socket implementation factory for the 131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * application. The factory can be specified only once. 131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * When an application creates a new datagram socket, the socket 13133a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * implementation factory's {@code createDatagramSocketImpl} method is 131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called to create the actual datagram socket implementation. 131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 13163a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * Passing {@code null} to the method is a no-op unless the factory 131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * was already set. 131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p>If there is a security manager, this method first calls 13203a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * the security manager's {@code checkSetFactory} method 132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to ensure the operation is allowed. 132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This could result in a SecurityException. 132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param fac the desired factory. 132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs when setting the 132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * datagram socket factory. 132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SocketException if the factory is already defined. 132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 13293a6411ec91b24e73f36301d0075bc7b052894ae9Yi Kong * {@code checkSetFactory} method doesn't allow the 133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski operation. 133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see 133251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski java.net.DatagramSocketImplFactory#createDatagramSocketImpl() 133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see SecurityManager#checkSetFactory 133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.3 133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static synchronized void 133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski setDatagramSocketImplFactory(DatagramSocketImplFactory fac) 133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 133951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 134051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (factory != null) { 134151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new SocketException("factory already defined"); 134251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 134351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager security = System.getSecurityManager(); 134451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (security != null) { 134551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkSetFactory(); 134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski factory = fac; 134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 1349f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski 135062098900d7201b01db7905a8ff1debea4b639a30Yi Kong /** 135162098900d7201b01db7905a8ff1debea4b639a30Yi Kong * Android-added: for testing and internal use. 135262098900d7201b01db7905a8ff1debea4b639a30Yi Kong * 135362098900d7201b01db7905a8ff1debea4b639a30Yi Kong * @hide internal use only 135462098900d7201b01db7905a8ff1debea4b639a30Yi Kong */ 1355e409de23a3281073142ff137b609778d6c70a31cYi Kong public FileDescriptor getFileDescriptor$() { 1356f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski return impl.fd; 1357f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski } 1358f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski 1359f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski /** 136062098900d7201b01db7905a8ff1debea4b639a30Yi Kong * Android-added: 1361f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * Sets the network interface used by this socket. Any packets sent 1362f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * via this socket are transmitted via the specified interface. Any 1363f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * packets received by this socket will come from the specified 1364f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * interface. Broadcast datagrams received on this interface will 1365f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * be processed by this socket. This corresponds to Linux's SO_BINDTODEVICE. 1366f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * 1367f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski * @hide used by GoogleTV for DHCP 1368f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski */ 1369f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski public void setNetworkInterface(NetworkInterface netInterface) throws SocketException { 1370f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski if (netInterface == null) { 1371f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski throw new NullPointerException("netInterface == null"); 1372f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski } 1373f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski try { 1374f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski Libcore.os.setsockoptIfreq(impl.fd, SOL_SOCKET, SO_BINDTODEVICE, netInterface.getName()); 1375f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski } catch (ErrnoException errnoException) { 1376f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski throw errnoException.rethrowAsSocketException(); 1377f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski } 1378f7ab2bc37debba91864bfec6572a3e7bbe994c58Piotr Jastrzebski } 137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 1380