Socket.java revision 0d93c38cc3c7a5001aece8a18cafc6d1fc7551f3
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.net;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.SocketChannel;
24f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.luni.net.PlainSocketImpl;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.Platform;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Provides a client-side TCP socket.
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Socket {
318cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private static SocketImplFactory factory;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
338cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    final SocketImpl impl;
348cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private final Proxy proxy;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
360371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    volatile boolean isCreated = false;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isBound = false;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isConnected = false;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isClosed = false;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isInputShutdown = false;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isOutputShutdown = false;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
438cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private InetAddress localAddress = Inet4Address.ANY;
448cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes
455e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes    private final Object connectLock = new Object();
461f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new unconnected socket. When a SocketImplFactory is defined it
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * creates the internal socket implementation, otherwise the default socket
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation will be used for this socket.
51f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImplFactory
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImpl
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket() {
568cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl();
578cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = null;
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new unconnected socket using the given proxy type. When a
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code SocketImplFactory} is defined it creates the internal socket
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * implementation, otherwise the default socket implementation will be used
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * for this socket.
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Example that will create a socket connection through a {@code SOCKS}
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * proxy server: <br>
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code Socket sock = new Socket(new Proxy(Proxy.Type.SOCKS, new
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * InetSocketAddress("test.domain.org", 2130)));}
70f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param proxy
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specified proxy for this socket.
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the argument {@code proxy} is {@code null} or of an
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             invalid type.
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given proxy.
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImplFactory
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImpl
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(Proxy proxy) {
838cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = proxy;
84b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (proxy == null || proxy.type() == Proxy.Type.HTTP) {
85b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Proxy is null or invalid type");
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetSocketAddress address = (InetSocketAddress) proxy.address();
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (null != address) {
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress addr = address.getAddress();
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String host;
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (null != addr) {
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                host = addr.getHostAddress();
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                host = address.getHostName();
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int port = address.getPort();
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkConnectPermission(host, port);
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl(proxy);
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1021f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    /**
1031f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * Tries to connect a socket to all IP addresses of the given hostname.
1041f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *
1051f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param dstName
1061f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the target host name or IP address to connect to.
1071f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param dstPort
1081f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the port on the target host to connect to.
1091f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param localAddress
1101f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the address on the local host to bind to.
1111f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param localPort
1121f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the port on the local host to bind to.
1131f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param streaming
1141f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            if {@code true} a streaming socket is returned, a datagram
1151f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            socket otherwise.
1161f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws UnknownHostException
1171f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if the host name could not be resolved into an IP address.
1181f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws IOException
1191f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if an error occurs while creating the socket.
1201f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws SecurityException
1211f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if a security manager exists and it denies the permission to
1221f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             connect to the given address and port.
1231f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     */
1241f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    private void tryAllAddresses(String dstName, int dstPort, InetAddress
1251f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            localAddress, int localPort, boolean streaming) throws IOException {
1261f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        InetAddress[] dstAddresses = InetAddress.getAllByName(dstName);
1271f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // Loop through all the destination addresses except the last, trying to
1281f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // connect to each one and ignoring errors. There must be at least one
1291f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // address, or getAllByName would have thrown UnknownHostException.
1301f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        InetAddress dstAddress;
1311f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        for (int i = 0; i < dstAddresses.length - 1; i++) {
1321f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            dstAddress = dstAddresses[i];
1331f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            try {
1341f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti                checkDestination(dstAddress, dstPort);
1358cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                startupSocket(dstAddress, dstPort, localAddress, localPort, streaming);
1361f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti                return;
1378cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes            } catch (SecurityException e1) {
1388cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes            } catch (IOException e2) {
1391f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            }
1401f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        }
1411f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
1421f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // Now try to connect to the last address in the array, handing back to
1431f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // the caller any exceptions that are thrown.
1441f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        dstAddress = dstAddresses[dstAddresses.length - 1];
1451f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        checkDestination(dstAddress, dstPort);
1461f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        startupSocket(dstAddress, dstPort, localAddress, localPort, streaming);
1471f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    }
1481f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstName} and {@code dstPort}. The socket is bound
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to any available port on the local host.
1531f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
1541f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
1551f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
1564c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
157f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstName
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1708cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String dstName, int dstPort) throws UnknownHostException, IOException {
1711f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        this(dstName, dstPort, null, 0);
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstName} and {@code dstPort}. On the local endpoint
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the socket is bound to the given address {@code localAddress} on port
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code localPort}.
179f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If {@code host} is {@code null} a loopback address is used to connect to.
1811f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
1821f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
1831f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
1844c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
185f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstName
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local host to bind to.
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local host to bind to.
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2028cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String dstName, int dstPort, InetAddress localAddress, int localPort) throws IOException {
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
2041f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        tryAllAddresses(dstName, dstPort, localAddress, localPort, true);
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming or datagram socket connected to the target host
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified by the parameters {@code hostName} and {@code port}. The socket
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is bound to any available port on the local host.
2111f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
2121f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
2131f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
2144c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
215f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param hostName
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param streaming
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if {@code true} a streaming socket is returned, a datagram
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            socket otherwise.
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@code Socket(String, int)} instead of this for streaming
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             sockets or an appropriate constructor of {@code
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             DatagramSocket} for UDP transport.
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
2358cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String hostName, int port, boolean streaming) throws IOException {
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
2371f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        tryAllAddresses(hostName, port, null, 0, streaming);
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstAddress} and {@code dstPort}. The socket is
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bound to any available port on the local host.
244f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host address to connect to.
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(InetAddress dstAddress, int dstPort) throws IOException {
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(dstAddress, dstPort);
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(dstAddress, dstPort, null, 0, true);
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstAddress} and {@code dstPort}. On the local
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * endpoint the socket is bound to the given address {@code localAddress} on
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * port {@code localPort}.
266f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host address to connect to.
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local host to bind to.
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local host to bind to.
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(InetAddress dstAddress, int dstPort,
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress localAddress, int localPort) throws IOException {
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(dstAddress, dstPort);
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(dstAddress, dstPort, localAddress, localPort, true);
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming or datagram socket connected to the target host
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified by the parameters {@code addr} and {@code port}. The socket is
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bound to any available port on the local host.
292f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param addr
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the Internet address to connect to.
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param streaming
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if {@code true} a streaming socket is returned, a datagram
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            socket otherwise.
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a security manager exists and it denies the permission to
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connect to the given address and port.
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@code Socket(InetAddress, int)} instead of this for
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             streaming sockets or an appropriate constructor of {@code
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             DatagramSocket} for UDP transport.
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
3108cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(InetAddress addr, int port, boolean streaming) throws IOException {
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(addr, port);
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(addr, port, null, 0, streaming);
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates an unconnected socket with the given socket implementation.
318f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
3198cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * @param impl
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket implementation to be used.
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3248cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    protected Socket(SocketImpl impl) throws SocketException {
3258cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = impl;
3268cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = null;
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the connection destination satisfies the security policy
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and the validity of the port range.
332f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param destAddr
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination host address.
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3388cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private void checkDestination(InetAddress destAddr, int dstPort) {
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (dstPort < 0 || dstPort > 65535) {
340b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Port out of range: " + dstPort);
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkConnectPermission(destAddr.getHostAddress(), dstPort);
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the connection destination satisfies the security policy.
347f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param hostname
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination hostname.
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkConnectPermission(String hostname, int dstPort) {
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkConnect(hostname, dstPort);
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the socket. It is not possible to reconnect or rebind to this
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket thereafter which means a new socket instance has to be created.
363f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket.
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void close() throws IOException {
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isClosed = true;
3698cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        // RI compatibility: the RI returns the any address (but the original local port) after close.
3708cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        localAddress = Inet4Address.ANY;
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.close();
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the IP address of the target host this socket is connected to.
376f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the IP address of the connected target host or {@code null} if
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         this socket is not yet connected.
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getInetAddress() {
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getInetAddress();
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets an input stream to read data from this socket.
389f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte-oriented input stream.
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the input stream or the
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             socket is in an invalid state.
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InputStream getInputStream() throws IOException {
3960371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isInputShutdown()) {
398b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket input is shutdown");
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getInputStream();
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_KEEPALIVE}.
405f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_KEEPALIVE} is
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_KEEPALIVE
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getKeepAlive() throws SocketException {
4130371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4148cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        return (Boolean) impl.getOption(SocketOptions.SO_KEEPALIVE);
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4188cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * Returns the local IP address this socket is bound to, or {@code InetAddress.ANY} if
4198cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * the socket is unbound.
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getLocalAddress() {
4228cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        return localAddress;
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4268cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * Returns the local port this socket is bound to, or -1 if the socket is unbound.
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getLocalPort() {
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getLocalPort();
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets an output stream to write data into this socket.
437f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte-oriented output stream.
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the output stream or the
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             socket is in an invalid state.
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public OutputStream getOutputStream() throws IOException {
4440371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isOutputShutdown()) {
446b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket output is shutdown");
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getOutputStream();
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the port number of the target host this socket is connected to.
453f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the port number of the connected target host or {@code 0} if this
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         socket is not yet connected.
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getPort() {
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getPort();
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4650371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes     * Gets the value of the socket option {@link SocketOptions#SO_LINGER}.
466f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_LINGER}
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         or {@code -1} if this option is disabled.
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_LINGER
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getSoLinger() throws SocketException {
4740371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4750371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        // The RI explicitly guarantees this idiocy in the SocketOptions.setOption documentation.
4760371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        Object value = impl.getOption(SocketOptions.SO_LINGER);
4770371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        if (value instanceof Integer) {
4780371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            return (Integer) value;
4790371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        } else {
4800371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            return -1;
4810371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        }
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the receive buffer size of this socket.
486f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_RCVBUF}.
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_RCVBUF
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getReceiveBufferSize() throws SocketException {
4930371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4940371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.SO_RCVBUF);
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the send buffer size of this socket.
499f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_SNDBUF}.
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_SNDBUF
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSendBufferSize() throws SocketException {
5060371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
5070371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.SO_SNDBUF);
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
51106f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Gets the socket {@link SocketOptions#SO_TIMEOUT receive timeout}.
512f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSoTimeout() throws SocketException {
5170371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
5180371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.SO_TIMEOUT);
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.TCP_NODELAY}.
523f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.TCP_NODELAY} is enabled,
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#TCP_NODELAY
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getTcpNoDelay() throws SocketException {
5310371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
5320371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Boolean) impl.getOption(SocketOptions.TCP_NODELAY);
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_KEEPALIVE} for this socket.
537f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
5380371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes     * @param keepAlive
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_KEEPALIVE
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
5440371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    public void setKeepAlive(boolean keepAlive) throws SocketException {
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (impl != null) {
5460371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            checkOpenAndCreate(true);
5470371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            impl.setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(keepAlive));
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the internal factory for creating socket implementations. This may
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * only be executed once during the lifetime of the application.
554f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param fac
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket implementation factory to be set.
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the factory has been already set.
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static synchronized void setSocketImplFactory(SocketImplFactory fac)
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkSetFactory();
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (factory != null) {
567b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Factory already set");
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        factory = fac;
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the send buffer size of this socket.
574f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param size
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer size in bytes. This value must be a positive number
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            greater than {@code 0}.
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the size or the given value
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is an invalid size.
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_SNDBUF
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSendBufferSize(int size) throws SocketException {
5840371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
586b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("size < 1");
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the receive buffer size of this socket.
593f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param size
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer size in bytes. This value must be a positive number
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            greater than {@code 0}.
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the size or the given value
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is an invalid size.
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_RCVBUF
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
602b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public synchronized void setReceiveBufferSize(int size) throws SocketException {
6030371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
605b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("size < 1");
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
6110371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes     * Sets the {@link SocketOptions#SO_LINGER} timeout in seconds.
612f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param on
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the linger timeout value in seconds.
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_LINGER
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSoLinger(boolean on, int timeout) throws SocketException {
6220371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
6230371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        // The RI explicitly guarantees this idiocy in the SocketOptions.setOption documentation.
624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (on && timeout < 0) {
625b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (on) {
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.setOption(SocketOptions.SO_LINGER, Integer.valueOf(timeout));
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.setOption(SocketOptions.SO_LINGER, Boolean.FALSE);
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
63506f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Sets the {@link SocketOptions#SO_TIMEOUT read timeout} in milliseconds for this socket.
6364e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * This receive timeout defines the period the socket will block waiting to
6374e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * receive data before throwing an {@code InterruptedIOException}. The value
6384e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * {@code 0} (default) is used to set an infinite timeout. To have effect
6394e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * this option must be set before the blocking method was called.
640f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
6414e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * @param timeout the timeout in milliseconds or 0 for no timeout.
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSoTimeout(int timeout) throws SocketException {
6460371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
648b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.TCP_NODELAY} for this socket.
655f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param on
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#TCP_NODELAY
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setTcpNoDelay(boolean on) throws SocketException {
6630371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a stream socket, binds it to the nominated local address/port,
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then connects it to the nominated destination address/port.
670f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination host address.
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local machine to bind.
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local machine to bind.
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             thrown if an error occurs during the bind or connect
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             operations.
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
6830371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    private void startupSocket(InetAddress dstAddress, int dstPort,
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress localAddress, int localPort, boolean streaming)
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (localPort < 0 || localPort > 65535) {
688b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Local port out of range: " + localPort);
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
6918cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        InetAddress addr = localAddress == null ? Inet4Address.ANY : localAddress;
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.create(streaming);
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
6960917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes                if (!streaming || !usingSocks()) {
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    impl.bind(addr, localPort);
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.connect(dstAddress, dstPort);
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isConnected = true;
7028cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7100917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes    private boolean usingSocks() {
7110917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes        return proxy != null && proxy.type() == Proxy.Type.SOCKS;
7120917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes    }
7130917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a {@code String} containing a concise, human-readable description of the
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket.
717f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the textual representation of this socket.
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
723f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return "Socket[unconnected]";
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.toString();
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the input stream of this socket. Any further data sent to this
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket will be discarded. Reading from this socket after this method has
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * been called will return the value {@code EOF}.
732f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket input stream.
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the input stream is already closed.
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void shutdownInput() throws IOException {
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isInputShutdown()) {
740b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket input is shutdown");
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
7420371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.shutdownInput();
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isInputShutdown = true;
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the output stream of this socket. All buffered data will be sent
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * followed by the termination sequence. Writing to the closed output stream
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * will cause an {@code IOException}.
751f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket output stream.
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the output stream is already closed.
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void shutdownOutput() throws IOException {
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isOutputShutdown()) {
759b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket output is shutdown");
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
7610371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.shutdownOutput();
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isOutputShutdown = true;
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the socket is closed, and throws an exception. Otherwise
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * creates the underlying SocketImpl.
769f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is closed.
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
7730371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    private void checkOpenAndCreate(boolean create) throws SocketException {
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isClosed()) {
775b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket is closed");
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!create) {
778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!isConnected()) {
779b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new SocketException("Socket is not connected");
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // a connected socket must be created
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /*
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * return directly to fix a possible bug, if !create, should return
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * here
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             */
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isCreated) {
790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (isCreated) {
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.create(true);
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (SocketException e) {
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SocketException(e.toString());
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the local address and port of this socket as a SocketAddress or
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code null} if the socket is unbound. This is useful on multihomed
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * hosts.
811f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the bound local socket address and port.
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getLocalSocketAddress() {
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new InetSocketAddress(getLocalAddress(), getLocalPort());
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the remote address and port of this socket as a {@code
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * SocketAddress} or {@code null} if the socket is not connected.
824f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the remote socket address and port.
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getRemoteSocketAddress() {
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new InetSocketAddress(getInetAddress(), getPort());
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is bound to a local address and port.
836f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is bound to a local address, {@code
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         false} otherwise.
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isBound() {
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isBound;
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is connected to a remote host.
846f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is connected, {@code false} otherwise.
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isConnected() {
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isConnected;
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is closed.
855f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is closed, {@code false} otherwise.
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isClosed() {
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isClosed;
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Binds this socket to the given local host address and port specified by
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the SocketAddress {@code localAddr}. If {@code localAddr} is set to
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code null}, this socket will be bound to an available local address on
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * any free port.
867f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddr
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific address and port on the local machine to bind to.
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported.
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already bound or an error occurs while
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             binding.
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void bind(SocketAddress localAddr) throws IOException {
8770371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isBound()) {
879b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new BindException("Socket is already bound");
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = 0;
883051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        InetAddress addr = Inet4Address.ANY;
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (localAddr != null) {
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(localAddr instanceof InetSocketAddress)) {
886b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new IllegalArgumentException("Local address not an InetSocketAddress: " +
887b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                        localAddr.getClass());
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetSocketAddress inetAddr = (InetSocketAddress) localAddr;
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((addr = inetAddr.getAddress()) == null) {
891b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new SocketException("Host is unresolved: " + inetAddr.getHostName());
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            port = inetAddr.getPort();
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.bind(addr, port);
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
9008cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Connects this socket to the given remote host address and port specified
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by the SocketAddress {@code remoteAddr}.
911f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param remoteAddr
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address and port of the remote host to connect to.
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported.
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already connected or an error occurs while
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connecting.
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void connect(SocketAddress remoteAddr) throws IOException {
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        connect(remoteAddr, 0);
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Connects this socket to the given remote host address and port specified
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by the SocketAddress {@code remoteAddr} with the specified timeout. The
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connecting method will block until the connection is established or an
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * error occurred.
929f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param remoteAddr
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address and port of the remote host to connect to.
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the timeout value in milliseconds or {@code 0} for an infinite
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            timeout.
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported or the
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             timeout value is negative.
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already connected or an error occurs while
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connecting.
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
9428cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public void connect(SocketAddress remoteAddr, int timeout) throws IOException {
9430371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
945b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isConnected()) {
948b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Already connected");
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (remoteAddr == null) {
951b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("remoteAddr == null");
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(remoteAddr instanceof InetSocketAddress)) {
955b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Remote address not an InetSocketAddress: " +
956b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                    remoteAddr.getClass());
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr;
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetAddress addr;
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((addr = inetAddr.getAddress()) == null) {
961b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Host is unresolved: " + inetAddr.getHostName());
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = inetAddr.getPort();
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(addr, port);
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (connectLock) {
967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!isBound()) {
9698cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                    // socket already created at this point by earlier call or
9700371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes                    // checkOpenAndCreate this caused us to lose socket
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // options on create
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // impl.create(true);
9730917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes                    if (!usingSocks()) {
974051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                        impl.bind(Inet4Address.ANY, 0);
975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    isBound = true;
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.connect(remoteAddr, timeout);
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isConnected = true;
9808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the incoming channel of the socket has already been
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * closed.
991f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if reading from this socket is not possible anymore,
993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isInputShutdown() {
996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isInputShutdown;
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1000f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Returns whether the outgoing channel of the socket has already been
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * closed.
1002f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if writing to this socket is not possible anymore,
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isOutputShutdown() {
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isOutputShutdown;
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_REUSEADDR} for this socket.
1012f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param reuse
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_REUSEADDR
1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setReuseAddress(boolean reuse) throws SocketException {
10200371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10210371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(reuse));
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1023adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_REUSEADDR}.
1026f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_REUSEADDR} is
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_REUSEADDR
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getReuseAddress() throws SocketException {
10340371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10350371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Boolean) impl.getOption(SocketOptions.SO_REUSEADDR);
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_OOBINLINE} for this socket.
1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * When this option is enabled urgent data can be received in-line with
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * normal data.
1042f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param oobinline
1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            whether this option is enabled or not.
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_OOBINLINE
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setOOBInline(boolean oobinline) throws SocketException {
10500371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10510371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        impl.setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(oobinline));
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_OOBINLINE}.
1056f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_OOBINLINE} is
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_OOBINLINE
1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getOOBInline() throws SocketException {
10640371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10650371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Boolean) impl.getOption(SocketOptions.SO_OOBINLINE);
1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
10692cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     * Sets the {@see SocketOptions#IP_TOS} value for every packet sent by this socket.
1070f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
10722cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     *             if the socket is closed or the option could not be set.
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setTrafficClass(int value) throws SocketException {
10750371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (value < 0 || value > 255) {
1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.IP_TOS, Integer.valueOf(value));
1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
10832cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     * Returns this socket's {@see SocketOptions#IP_TOS} setting.
1084f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
10862cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     *             if the socket is closed or the option is invalid.
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getTrafficClass() throws SocketException {
10890371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10900371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.IP_TOS);
1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sends the given single byte data which is represented by the lowest octet
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of {@code value} as "TCP urgent data".
1096f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the byte of urgent data to be sent.
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while sending urgent data.
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void sendUrgentData(int value) throws IOException {
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.sendUrgentData(value);
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Set the appropriate flags for a socket created by {@code
1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ServerSocket.accept()}.
1109f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ServerSocket#implAccept
1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void accepted() {
1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isCreated = isBound = isConnected = true;
11148cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        cacheLocalAddress();
11158cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    }
11168cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes
11178cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private void cacheLocalAddress() {
11183db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes        this.localAddress = Platform.NETWORK.getSocketLocalAddress(impl.fd);
1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
11220d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * Returns this socket's {@code SocketChannel}, if one exists. A channel is
11230d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * available only if this socket wraps a channel. (That is, you can go from a
11240d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * channel to a socket and back again, but you can't go from an arbitrary socket to a channel.)
11250d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * In practice, this means that the socket must have been created by
11260d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * {@link java.nio.channels.ServerSocketChannel#accept} or
11270d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * {@link java.nio.channels.SocketChannel#open}.
1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketChannel getChannel() {
1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets performance preferences for connectionTime, latency and bandwidth.
1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method does currently nothing.
1137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param connectionTime
1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of a short connecting
1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            time.
1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param latency
1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of low latency.
1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bandwidth
1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of high bandwidth.
1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
11460371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Our socket implementation only provide one protocol: TCP/IP, so
1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // we do nothing for this method
1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1151