Socket.java revision ad41624e761bcf1af9c8008eb45187fc13983717
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     * @see SocketImplFactory
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketImpl
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(Proxy proxy) {
808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = proxy;
81b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (proxy == null || proxy.type() == Proxy.Type.HTTP) {
82b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Proxy is null or invalid type");
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetSocketAddress address = (InetSocketAddress) proxy.address();
85b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes        if (address != null) {
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress addr = address.getAddress();
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String host;
88b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes            if (addr != null) {
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                host = addr.getHostAddress();
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                host = address.getHostName();
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int port = address.getPort();
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
958cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl(proxy);
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
981f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    /**
991f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * Tries to connect a socket to all IP addresses of the given hostname.
1001f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *
1011f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param dstName
1021f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the target host name or IP address to connect to.
1031f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param dstPort
1041f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the port on the target host to connect to.
1051f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param localAddress
1061f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the address on the local host to bind to.
1071f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param localPort
1081f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            the port on the local host to bind to.
1091f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @param streaming
1101f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            if {@code true} a streaming socket is returned, a datagram
1111f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *            socket otherwise.
1121f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws UnknownHostException
1131f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if the host name could not be resolved into an IP address.
1141f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * @throws IOException
1151f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     *             if an error occurs while creating the socket.
1161f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     */
1171f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    private void tryAllAddresses(String dstName, int dstPort, InetAddress
1181f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            localAddress, int localPort, boolean streaming) throws IOException {
1191f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        InetAddress[] dstAddresses = InetAddress.getAllByName(dstName);
1201f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // Loop through all the destination addresses except the last, trying to
1211f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // connect to each one and ignoring errors. There must be at least one
1221f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // address, or getAllByName would have thrown UnknownHostException.
1231f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        InetAddress dstAddress;
1241f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        for (int i = 0; i < dstAddresses.length - 1; i++) {
1251f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            dstAddress = dstAddresses[i];
1261f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            try {
1271f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti                checkDestination(dstAddress, dstPort);
1288cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                startupSocket(dstAddress, dstPort, localAddress, localPort, streaming);
1291f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti                return;
130ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes            } catch (IOException ex) {
1311f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti            }
1321f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        }
1331f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
1341f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // Now try to connect to the last address in the array, handing back to
1351f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        // the caller any exceptions that are thrown.
1361f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        dstAddress = dstAddresses[dstAddresses.length - 1];
1371f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        checkDestination(dstAddress, dstPort);
1381f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        startupSocket(dstAddress, dstPort, localAddress, localPort, streaming);
1391f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti    }
1401f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstName} and {@code dstPort}. The socket is bound
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to any available port on the local host.
1451f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
1461f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
1471f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
1484c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
149f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstName
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1598cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String dstName, int dstPort) throws UnknownHostException, IOException {
1601f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        this(dstName, dstPort, null, 0);
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstName} and {@code dstPort}. On the local endpoint
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the socket is bound to the given address {@code localAddress} on port
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code localPort}.
168f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * If {@code host} is {@code null} a loopback address is used to connect to.
1701f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
1711f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
1721f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
1734c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
174f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstName
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local host to bind to.
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local host to bind to.
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1888cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String dstName, int dstPort, InetAddress localAddress, int localPort) throws IOException {
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
1901f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        tryAllAddresses(dstName, dstPort, localAddress, localPort, true);
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming or datagram socket connected to the target host
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified by the parameters {@code hostName} and {@code port}. The socket
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * is bound to any available port on the local host.
1971f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * <p><strong>Implementation note:</strong> this implementation tries each
1981f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * IP address for the given hostname until it either connects successfully
1991f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti     * or it exhausts the set. It will try both IPv4 and IPv6 addresses in the
2004c5cbf2953ada194c4dc9d7b387615b1c6fe3e63Elliott Hughes     * order specified by the system property {@code "java.net.preferIPv6Addresses"}.
201f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param hostName
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host name or IP address to connect to.
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param streaming
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if {@code true} a streaming socket is returned, a datagram
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            socket otherwise.
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws UnknownHostException
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the host name could not be resolved into an IP address.
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@code Socket(String, int)} instead of this for streaming
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             sockets or an appropriate constructor of {@code
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             DatagramSocket} for UDP transport.
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
2188cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(String hostName, int port, boolean streaming) throws IOException {
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
2201f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti        tryAllAddresses(hostName, port, null, 0, streaming);
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstAddress} and {@code dstPort}. The socket is
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bound to any available port on the local host.
227f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host address to connect to.
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(InetAddress dstAddress, int dstPort) throws IOException {
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(dstAddress, dstPort);
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(dstAddress, dstPort, null, 0, true);
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming socket connected to the target host specified by
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the parameters {@code dstAddress} and {@code dstPort}. On the local
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * endpoint the socket is bound to the given address {@code localAddress} on
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * port {@code localPort}.
246f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the target host address to connect to.
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local host to bind to.
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local host to bind to.
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Socket(InetAddress dstAddress, int dstPort,
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress localAddress, int localPort) throws IOException {
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(dstAddress, dstPort);
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(dstAddress, dstPort, localAddress, localPort, true);
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new streaming or datagram socket connected to the target host
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified by the parameters {@code addr} and {@code port}. The socket is
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * bound to any available port on the local host.
269f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param addr
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the Internet address to connect to.
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param port
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the target host to connect to.
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param streaming
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            if {@code true} a streaming socket is returned, a datagram
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            socket otherwise.
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @deprecated Use {@code Socket(InetAddress, int)} instead of this for
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             streaming sockets or an appropriate constructor of {@code
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             DatagramSocket} for UDP transport.
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Deprecated
2848cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public Socket(InetAddress addr, int port, boolean streaming) throws IOException {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this();
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(addr, port);
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        startupSocket(addr, port, null, 0, streaming);
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates an unconnected socket with the given socket implementation.
292f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
2938cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * @param impl
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket implementation to be used.
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the socket.
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
2988cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    protected Socket(SocketImpl impl) throws SocketException {
2998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.impl = impl;
3008cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        this.proxy = null;
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the connection destination satisfies the security policy
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and the validity of the port range.
306f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param destAddr
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination host address.
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
3128cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private void checkDestination(InetAddress destAddr, int dstPort) {
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (dstPort < 0 || dstPort > 65535) {
314b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Port out of range: " + dstPort);
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the socket. It is not possible to reconnect or rebind to this
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket thereafter which means a new socket instance has to be created.
321f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket.
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void close() throws IOException {
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isClosed = true;
3278cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        // RI compatibility: the RI returns the any address (but the original local port) after close.
3288cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        localAddress = Inet4Address.ANY;
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.close();
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the IP address of the target host this socket is connected to.
334f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the IP address of the connected target host or {@code null} if
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         this socket is not yet connected.
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getInetAddress() {
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getInetAddress();
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets an input stream to read data from this socket.
347f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte-oriented input stream.
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the input stream or the
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             socket is in an invalid state.
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InputStream getInputStream() throws IOException {
3540371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isInputShutdown()) {
356b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket input is shutdown");
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getInputStream();
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_KEEPALIVE}.
363f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_KEEPALIVE} is
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_KEEPALIVE
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getKeepAlive() throws SocketException {
3710371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
3728cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        return (Boolean) impl.getOption(SocketOptions.SO_KEEPALIVE);
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3768cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * Returns the local IP address this socket is bound to, or {@code InetAddress.ANY} if
3778cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * the socket is unbound.
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public InetAddress getLocalAddress() {
3808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        return localAddress;
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
3848cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes     * Returns the local port this socket is bound to, or -1 if the socket is unbound.
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getLocalPort() {
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return -1;
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getLocalPort();
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets an output stream to write data into this socket.
395f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the byte-oriented output stream.
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while creating the output stream or the
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             socket is in an invalid state.
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public OutputStream getOutputStream() throws IOException {
4020371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isOutputShutdown()) {
404b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket output is shutdown");
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getOutputStream();
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the port number of the target host this socket is connected to.
411f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the port number of the connected target host or {@code 0} if this
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         socket is not yet connected.
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getPort() {
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return 0;
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.getPort();
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
4230371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes     * Gets the value of the socket option {@link SocketOptions#SO_LINGER}.
424f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_LINGER}
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         or {@code -1} if this option is disabled.
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_LINGER
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getSoLinger() throws SocketException {
4320371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4330371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        // The RI explicitly guarantees this idiocy in the SocketOptions.setOption documentation.
4340371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        Object value = impl.getOption(SocketOptions.SO_LINGER);
4350371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        if (value instanceof Integer) {
4360371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            return (Integer) value;
4370371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        } else {
4380371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            return -1;
4390371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        }
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the receive buffer size of this socket.
444f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_RCVBUF}.
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_RCVBUF
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getReceiveBufferSize() throws SocketException {
4510371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4520371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.SO_RCVBUF);
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the send buffer size of this socket.
457f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value of the option {@code SocketOptions.SO_SNDBUF}.
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_SNDBUF
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSendBufferSize() throws SocketException {
4640371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4650371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.SO_SNDBUF);
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
46906f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Gets the socket {@link SocketOptions#SO_TIMEOUT receive timeout}.
470f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized int getSoTimeout() throws SocketException {
4750371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4760371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.SO_TIMEOUT);
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.TCP_NODELAY}.
481f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.TCP_NODELAY} is enabled,
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#TCP_NODELAY
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getTcpNoDelay() throws SocketException {
4890371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
4900371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Boolean) impl.getOption(SocketOptions.TCP_NODELAY);
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_KEEPALIVE} for this socket.
495f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
4960371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes     * @param keepAlive
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_KEEPALIVE
501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
5020371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    public void setKeepAlive(boolean keepAlive) throws SocketException {
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (impl != null) {
5040371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            checkOpenAndCreate(true);
5050371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes            impl.setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(keepAlive));
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the internal factory for creating socket implementations. This may
511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * only be executed once during the lifetime of the application.
512f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param fac
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the socket implementation factory to be set.
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the factory has been already set.
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static synchronized void setSocketImplFactory(SocketImplFactory fac)
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (factory != null) {
521b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Factory already set");
522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        factory = fac;
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the send buffer size of this socket.
528f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param size
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer size in bytes. This value must be a positive number
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            greater than {@code 0}.
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the size or the given value
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is an invalid size.
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_SNDBUF
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSendBufferSize(int size) throws SocketException {
5380371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
540b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("size < 1");
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the receive buffer size of this socket.
547f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param size
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer size in bytes. This value must be a positive number
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            greater than {@code 0}.
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the size or the given value
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             is an invalid size.
554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_RCVBUF
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
556b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    public synchronized void setReceiveBufferSize(int size) throws SocketException {
5570371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size < 1) {
559b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("size < 1");
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
5650371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes     * Sets the {@link SocketOptions#SO_LINGER} timeout in seconds.
566f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param on
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the linger timeout value in seconds.
571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_LINGER
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSoLinger(boolean on, int timeout) throws SocketException {
5760371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
5770371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        // The RI explicitly guarantees this idiocy in the SocketOptions.setOption documentation.
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (on && timeout < 0) {
579b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (on) {
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.setOption(SocketOptions.SO_LINGER, Integer.valueOf(timeout));
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.setOption(SocketOptions.SO_LINGER, Boolean.FALSE);
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
58906f47d3e721e7032c97f80b3b2c7d25a8e6f2d21Brian Carlstrom     * Sets the {@link SocketOptions#SO_TIMEOUT read timeout} in milliseconds for this socket.
5904e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * This receive timeout defines the period the socket will block waiting to
5914e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * receive data before throwing an {@code InterruptedIOException}. The value
5924e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * {@code 0} (default) is used to set an infinite timeout. To have effect
5934e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * this option must be set before the blocking method was called.
594f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
5954e4000ed98f9056639fba0713a3fd3caacf9746cElliott Hughes     * @param timeout the timeout in milliseconds or 0 for no timeout.
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public synchronized void setSoTimeout(int timeout) throws SocketException {
6000371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
602b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.TCP_NODELAY} for this socket.
609f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param on
611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#TCP_NODELAY
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setTcpNoDelay(boolean on) throws SocketException {
6170371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a stream socket, binds it to the nominated local address/port,
623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then connects it to the nominated destination address/port.
624f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstAddress
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the destination host address.
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param dstPort
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the destination host.
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddress
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address on the local machine to bind.
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localPort
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the port on the local machine to bind.
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             thrown if an error occurs during the bind or connect
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             operations.
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
6370371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    private void startupSocket(InetAddress dstAddress, int dstPort,
638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetAddress localAddress, int localPort, boolean streaming)
639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws IOException {
640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (localPort < 0 || localPort > 65535) {
642b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Local port out of range: " + localPort);
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
6458cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        InetAddress addr = localAddress == null ? Inet4Address.ANY : localAddress;
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            impl.create(streaming);
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
6500917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes                if (!streaming || !usingSocks()) {
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    impl.bind(addr, localPort);
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.connect(dstAddress, dstPort);
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isConnected = true;
6568cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
6640917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes    private boolean usingSocks() {
6650917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes        return proxy != null && proxy.type() == Proxy.Type.SOCKS;
6660917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes    }
6670917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a {@code String} containing a concise, human-readable description of the
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket.
671f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the textual representation of this socket.
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
677f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            return "Socket[unconnected]";
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return impl.toString();
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the input stream of this socket. Any further data sent to this
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * socket will be discarded. Reading from this socket after this method has
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * been called will return the value {@code EOF}.
686f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket input stream.
689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the input stream is already closed.
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void shutdownInput() throws IOException {
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isInputShutdown()) {
694b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket input is shutdown");
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
6960371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.shutdownInput();
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isInputShutdown = true;
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes the output stream of this socket. All buffered data will be sent
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * followed by the termination sequence. Writing to the closed output stream
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * will cause an {@code IOException}.
705f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing the socket output stream.
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the output stream is already closed.
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void shutdownOutput() throws IOException {
712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isOutputShutdown()) {
713b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket output is shutdown");
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
7150371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(false);
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.shutdownOutput();
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isOutputShutdown = true;
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Checks whether the socket is closed, and throws an exception. Otherwise
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * creates the underlying SocketImpl.
723f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is closed.
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
7270371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    private void checkOpenAndCreate(boolean create) throws SocketException {
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isClosed()) {
729b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Socket is closed");
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!create) {
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!isConnected()) {
733b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new SocketException("Socket is not connected");
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // a connected socket must be created
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            /*
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * return directly to fix a possible bug, if !create, should return
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             * here
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project             */
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isCreated) {
744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (isCreated) {
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.create(true);
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (SocketException e) {
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw new SocketException(e.toString());
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isCreated = true;
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the local address and port of this socket as a SocketAddress or
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code null} if the socket is unbound. This is useful on multihomed
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * hosts.
765f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the bound local socket address and port.
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getLocalSocketAddress() {
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isBound()) {
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new InetSocketAddress(getLocalAddress(), getLocalPort());
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the remote address and port of this socket as a {@code
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * SocketAddress} or {@code null} if the socket is not connected.
778f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the remote socket address and port.
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketAddress getRemoteSocketAddress() {
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isConnected()) {
783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new InetSocketAddress(getInetAddress(), getPort());
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is bound to a local address and port.
790f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is bound to a local address, {@code
792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         false} otherwise.
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isBound() {
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isBound;
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is connected to a remote host.
800f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is connected, {@code false} otherwise.
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isConnected() {
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isConnected;
805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether this socket is closed.
809f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the socket is closed, {@code false} otherwise.
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isClosed() {
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isClosed;
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Binds this socket to the given local host address and port specified by
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the SocketAddress {@code localAddr}. If {@code localAddr} is set to
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code null}, this socket will be bound to an available local address on
820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * any free port.
821f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param localAddr
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the specific address and port on the local machine to bind to.
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported.
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already bound or an error occurs while
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             binding.
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void bind(SocketAddress localAddr) throws IOException {
8310371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isBound()) {
833b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new BindException("Socket is already bound");
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = 0;
837051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti        InetAddress addr = Inet4Address.ANY;
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (localAddr != null) {
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!(localAddr instanceof InetSocketAddress)) {
840b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new IllegalArgumentException("Local address not an InetSocketAddress: " +
841b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                        localAddr.getClass());
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            InetSocketAddress inetAddr = (InetSocketAddress) localAddr;
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((addr = inetAddr.getAddress()) == null) {
845b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new SocketException("Host is unresolved: " + inetAddr.getHostName());
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            port = inetAddr.getPort();
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.bind(addr, port);
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isBound = true;
8548cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Connects this socket to the given remote host address and port specified
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by the SocketAddress {@code remoteAddr}.
865f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param remoteAddr
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address and port of the remote host to connect to.
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported.
870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already connected or an error occurs while
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connecting.
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void connect(SocketAddress remoteAddr) throws IOException {
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        connect(remoteAddr, 0);
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Connects this socket to the given remote host address and port specified
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * by the SocketAddress {@code remoteAddr} with the specified timeout. The
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * connecting method will block until the connection is established or an
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * error occurred.
883f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param remoteAddr
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the address and port of the remote host to connect to.
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param timeout
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the timeout value in milliseconds or {@code 0} for an infinite
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            timeout.
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the given SocketAddress is invalid or not supported or the
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             timeout value is negative.
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the socket is already connected or an error occurs while
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             connecting.
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
8968cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    public void connect(SocketAddress remoteAddr, int timeout) throws IOException {
8970371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (timeout < 0) {
899b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("timeout < 0");
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (isConnected()) {
902b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Already connected");
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (remoteAddr == null) {
905b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("remoteAddr == null");
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!(remoteAddr instanceof InetSocketAddress)) {
909b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("Remote address not an InetSocketAddress: " +
910b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                    remoteAddr.getClass());
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr;
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        InetAddress addr;
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((addr = inetAddr.getAddress()) == null) {
915b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new SocketException("Host is unresolved: " + inetAddr.getHostName());
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int port = inetAddr.getPort();
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkDestination(addr, port);
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (connectLock) {
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!isBound()) {
9238cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                    // socket already created at this point by earlier call or
9240371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes                    // checkOpenAndCreate this caused us to lose socket
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // options on create
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // impl.create(true);
9270917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes                    if (!usingSocks()) {
928051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti                        impl.bind(Inet4Address.ANY, 0);
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    isBound = true;
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.connect(remoteAddr, timeout);
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                isConnected = true;
9348cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes                cacheLocalAddress();
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                impl.close();
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                throw e;
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the incoming channel of the socket has already been
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * closed.
945f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if reading from this socket is not possible anymore,
947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isInputShutdown() {
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isInputShutdown;
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
954f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Returns whether the outgoing channel of the socket has already been
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * closed.
956f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if writing to this socket is not possible anymore,
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code false} otherwise.
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean isOutputShutdown() {
961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return isOutputShutdown;
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_REUSEADDR} for this socket.
966f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param reuse
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the state whether this option is enabled or not.
969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_REUSEADDR
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setReuseAddress(boolean reuse) throws SocketException {
9740371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
9750371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(reuse));
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_REUSEADDR}.
980f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_REUSEADDR} is
982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_REUSEADDR
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getReuseAddress() throws SocketException {
9880371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
9890371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Boolean) impl.getOption(SocketOptions.SO_REUSEADDR);
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
992adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the state of the {@code SocketOptions.SO_OOBINLINE} for this socket.
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * When this option is enabled urgent data can be received in-line with
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * normal data.
996f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param oobinline
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            whether this option is enabled or not.
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while setting the option.
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_OOBINLINE
1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setOOBInline(boolean oobinline) throws SocketException {
10040371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10050371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        impl.setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(oobinline));
1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Gets the setting of the socket option {@code SocketOptions.SO_OOBINLINE}.
1010f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1011adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the {@code SocketOptions.SO_OOBINLINE} is
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         enabled, {@code false} otherwise.
1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while reading the socket option.
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see SocketOptions#SO_OOBINLINE
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getOOBInline() throws SocketException {
10180371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10190371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Boolean) impl.getOption(SocketOptions.SO_OOBINLINE);
1020adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1021adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
10232cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     * Sets the {@see SocketOptions#IP_TOS} value for every packet sent by this socket.
1024f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
10262cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     *             if the socket is closed or the option could not be set.
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setTrafficClass(int value) throws SocketException {
10290371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (value < 0 || value > 255) {
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IllegalArgumentException();
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.setOption(SocketOptions.IP_TOS, Integer.valueOf(value));
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
10372cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     * Returns this socket's {@see SocketOptions#IP_TOS} setting.
1038f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SocketException
10402cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes     *             if the socket is closed or the option is invalid.
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getTrafficClass() throws SocketException {
10430371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        checkOpenAndCreate(true);
10440371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes        return (Integer) impl.getOption(SocketOptions.IP_TOS);
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sends the given single byte data which is represented by the lowest octet
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of {@code value} as "TCP urgent data".
1050f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param value
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the byte of urgent data to be sent.
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while sending urgent data.
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void sendUrgentData(int value) throws IOException {
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        impl.sendUrgentData(value);
1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Set the appropriate flags for a socket created by {@code
1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * ServerSocket.accept()}.
1063f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see ServerSocket#implAccept
1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void accepted() {
1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isCreated = isBound = isConnected = true;
10688cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes        cacheLocalAddress();
10698cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    }
10708cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes
10718cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes    private void cacheLocalAddress() {
10723db0d1b07a79c3c871b0aa0929674adae3081b4fElliott Hughes        this.localAddress = Platform.NETWORK.getSocketLocalAddress(impl.fd);
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
10760d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * Returns this socket's {@code SocketChannel}, if one exists. A channel is
10770d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * available only if this socket wraps a channel. (That is, you can go from a
10780d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * channel to a socket and back again, but you can't go from an arbitrary socket to a channel.)
10790d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * In practice, this means that the socket must have been created by
10800d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * {@link java.nio.channels.ServerSocketChannel#accept} or
10810d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes     * {@link java.nio.channels.SocketChannel#open}.
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public SocketChannel getChannel() {
1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets performance preferences for connectionTime, latency and bandwidth.
1089adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This method does currently nothing.
1091f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param connectionTime
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of a short connecting
1094adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            time.
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param latency
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of low latency.
1097adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bandwidth
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value representing the importance of high bandwidth.
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
11000371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes    public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Our socket implementation only provide one protocol: TCP/IP, so
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // we do nothing for this method
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1105