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 20dc33f53f38600943c84146320c748e3c46fd2e7bElliott Hughesimport java.io.FileDescriptor; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.InputStream; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.SocketChannel; 250b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughesimport libcore.io.IoBridge; 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) { 80b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes if (proxy == null || proxy.type() == Proxy.Type.HTTP) { 81ae06196267319eef727892d9e13bdecea3482e34Elliott Hughes throw new IllegalArgumentException("Invalid proxy: " + proxy); 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 83ae06196267319eef727892d9e13bdecea3482e34Elliott Hughes this.proxy = proxy; 848cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes this.impl = factory != null ? factory.createSocketImpl() : new PlainSocketImpl(proxy); 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 871f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti /** 881f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * Tries to connect a socket to all IP addresses of the given hostname. 891f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * 901f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * @param dstName 911f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * the target host name or IP address to connect to. 921f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * @param dstPort 931f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * the port on the target host to connect to. 941f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * @param localAddress 951f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * the address on the local host to bind to. 961f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * @param localPort 971f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * the port on the local host to bind to. 981f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * @param streaming 991f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * if {@code true} a streaming socket is returned, a datagram 1001f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * socket otherwise. 1011f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * @throws UnknownHostException 1021f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * if the host name could not be resolved into an IP address. 1031f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * @throws IOException 1041f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti * if an error occurs while creating the socket. 1051f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti */ 1061f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti private void tryAllAddresses(String dstName, int dstPort, InetAddress 1071f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti localAddress, int localPort, boolean streaming) throws IOException { 1081f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti InetAddress[] dstAddresses = InetAddress.getAllByName(dstName); 1091f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti // Loop through all the destination addresses except the last, trying to 1101f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti // connect to each one and ignoring errors. There must be at least one 1111f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti // address, or getAllByName would have thrown UnknownHostException. 1121f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti InetAddress dstAddress; 1131f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti for (int i = 0; i < dstAddresses.length - 1; i++) { 1141f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti dstAddress = dstAddresses[i]; 1151f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti try { 1161f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti checkDestination(dstAddress, dstPort); 1178cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes startupSocket(dstAddress, dstPort, localAddress, localPort, streaming); 1181f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti return; 119ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes } catch (IOException ex) { 1201f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti } 1211f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti } 1221f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti 1231f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti // Now try to connect to the last address in the array, handing back to 1241f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti // the caller any exceptions that are thrown. 1251f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti dstAddress = dstAddresses[dstAddresses.length - 1]; 1261f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti checkDestination(dstAddress, dstPort); 1271f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti startupSocket(dstAddress, dstPort, localAddress, localPort, streaming); 1281f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti } 1291f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new streaming socket connected to the target host specified by 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parameters {@code dstName} and {@code dstPort}. The socket is bound 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * to any available port on the local host. 134ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * 135ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * <p>This implementation tries each IP address for the given hostname (in 136ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * <a href="http://www.ietf.org/rfc/rfc3484.txt">RFC 3484</a> order) 137ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * until it either connects successfully or it exhausts the set. 138f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstName 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the target host name or IP address to connect to. 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstPort 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the target host to connect to. 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the host name could not be resolved into an IP address. 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the socket. 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1488cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public Socket(String dstName, int dstPort) throws UnknownHostException, IOException { 1491f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti this(dstName, dstPort, null, 0); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new streaming socket connected to the target host specified by 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parameters {@code dstName} and {@code dstPort}. On the local endpoint 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the socket is bound to the given address {@code localAddress} on port 156ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * {@code localPort}. If {@code host} is {@code null} a loopback address is used to connect to. 157f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 158ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * <p>This implementation tries each IP address for the given hostname (in 159ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * <a href="http://www.ietf.org/rfc/rfc3484.txt">RFC 3484</a> order) 160ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * until it either connects successfully or it exhausts the set. 161f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstName 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the target host name or IP address to connect to. 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstPort 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the target host to connect to. 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param localAddress 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the address on the local host to bind to. 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param localPort 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the local host to bind to. 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the host name could not be resolved into an IP address. 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the socket. 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1758cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public Socket(String dstName, int dstPort, InetAddress localAddress, int localPort) throws IOException { 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(); 1771f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti tryAllAddresses(dstName, dstPort, localAddress, localPort, true); 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new streaming or datagram socket connected to the target host 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified by the parameters {@code hostName} and {@code port}. The socket 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is bound to any available port on the local host. 184ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * 185ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * <p>This implementation tries each IP address for the given hostname (in 186ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * <a href="http://www.ietf.org/rfc/rfc3484.txt">RFC 3484</a> order) 187ae394a866dd86df8819b652dfe00b3d2c7ee204cElliott Hughes * until it either connects successfully or it exhausts the set. 188f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param hostName 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the target host name or IP address to connect to. 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param port 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the target host to connect to. 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param streaming 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code true} a streaming socket is returned, a datagram 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket otherwise. 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws UnknownHostException 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the host name could not be resolved into an IP address. 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the socket. 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @deprecated Use {@code Socket(String, int)} instead of this for streaming 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * sockets or an appropriate constructor of {@code 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * DatagramSocket} for UDP transport. 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Deprecated 2058cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public Socket(String hostName, int port, boolean streaming) throws IOException { 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(); 2071f2d2815dc31bf3c464eec6d1de7e428d7f1dcf6Lorenzo Colitti tryAllAddresses(hostName, port, null, 0, streaming); 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new streaming socket connected to the target host specified by 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parameters {@code dstAddress} and {@code dstPort}. The socket is 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * bound to any available port on the local host. 214f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstAddress 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the target host address to connect to. 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstPort 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the target host to connect to. 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the socket. 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Socket(InetAddress dstAddress, int dstPort) throws IOException { 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(); 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkDestination(dstAddress, dstPort); 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startupSocket(dstAddress, dstPort, null, 0, true); 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new streaming socket connected to the target host specified by 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parameters {@code dstAddress} and {@code dstPort}. On the local 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * endpoint the socket is bound to the given address {@code localAddress} on 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * port {@code localPort}. 233f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstAddress 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the target host address to connect to. 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstPort 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the target host to connect to. 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param localAddress 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the address on the local host to bind to. 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param localPort 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the local host to bind to. 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the socket. 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Socket(InetAddress dstAddress, int dstPort, 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetAddress localAddress, int localPort) throws IOException { 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(); 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkDestination(dstAddress, dstPort); 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startupSocket(dstAddress, dstPort, localAddress, localPort, true); 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new streaming or datagram socket connected to the target host 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specified by the parameters {@code addr} and {@code port}. The socket is 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * bound to any available port on the local host. 256f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param addr 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the Internet address to connect to. 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param port 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the target host to connect to. 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param streaming 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code true} a streaming socket is returned, a datagram 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket otherwise. 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the socket. 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @deprecated Use {@code Socket(InetAddress, int)} instead of this for 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * streaming sockets or an appropriate constructor of {@code 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * DatagramSocket} for UDP transport. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Deprecated 2718cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public Socket(InetAddress addr, int port, boolean streaming) throws IOException { 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this(); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkDestination(addr, port); 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startupSocket(addr, port, null, 0, streaming); 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an unconnected socket with the given socket implementation. 279f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 2808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes * @param impl 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the socket implementation to be used. 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the socket. 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2858cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes protected Socket(SocketImpl impl) throws SocketException { 2868cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes this.impl = impl; 2878cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes this.proxy = null; 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks whether the connection destination satisfies the security policy 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and the validity of the port range. 293f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param destAddr 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the destination host address. 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstPort 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the destination host. 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 2998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private void checkDestination(InetAddress destAddr, int dstPort) { 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (dstPort < 0 || dstPort > 65535) { 301b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Port out of range: " + dstPort); 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the socket. It is not possible to reconnect or rebind to this 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket thereafter which means a new socket instance has to be created. 308f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while closing the socket. 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void close() throws IOException { 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isClosed = true; 3148cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // RI compatibility: the RI returns the any address (but the original local port) after close. 3158cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes localAddress = Inet4Address.ANY; 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.close(); 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 320a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns the IP address of the target host this socket is connected to, or null if this 321a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * socket is not yet connected. 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InetAddress getInetAddress() { 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected()) { 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return impl.getInetAddress(); 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 331a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns an input stream to read data from this socket. 332f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the byte-oriented input stream. 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the input stream or the 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket is in an invalid state. 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InputStream getInputStream() throws IOException { 3390371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(false); 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isInputShutdown()) { 341b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Socket input is shutdown"); 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return impl.getInputStream(); 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 347a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@link SocketOptions#SO_KEEPALIVE} setting. 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getKeepAlive() throws SocketException { 3500371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 3518cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes return (Boolean) impl.getOption(SocketOptions.SO_KEEPALIVE); 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3558cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes * Returns the local IP address this socket is bound to, or {@code InetAddress.ANY} if 3568cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes * the socket is unbound. 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public InetAddress getLocalAddress() { 3598cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes return localAddress; 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 3638cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes * Returns the local port this socket is bound to, or -1 if the socket is unbound. 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getLocalPort() { 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isBound()) { 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return -1; 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return impl.getLocalPort(); 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 373a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns an output stream to write data into this socket. 374f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the byte-oriented output stream. 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while creating the output stream or the 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket is in an invalid state. 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public OutputStream getOutputStream() throws IOException { 3810371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(false); 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOutputShutdown()) { 383b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Socket output is shutdown"); 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return impl.getOutputStream(); 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 389a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns the port number of the target host this socket is connected to, or 0 if this socket 390a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * is not yet connected. 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getPort() { 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected()) { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 0; 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return impl.getPort(); 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 400a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@link SocketOptions#SO_LINGER linger} timeout in seconds, or -1 401a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * for no linger (i.e. {@code close} will return immediately). 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getSoLinger() throws SocketException { 4040371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 4050371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // The RI explicitly guarantees this idiocy in the SocketOptions.setOption documentation. 4060371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes Object value = impl.getOption(SocketOptions.SO_LINGER); 4070371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes if (value instanceof Integer) { 4080371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Integer) value; 4090371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } else { 4100371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return -1; 4110371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 415a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@link SocketOptions#SO_RCVBUF receive buffer size}. 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized int getReceiveBufferSize() throws SocketException { 4180371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 4190371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Integer) impl.getOption(SocketOptions.SO_RCVBUF); 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 423a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@link SocketOptions#SO_SNDBUF send buffer size}. 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized int getSendBufferSize() throws SocketException { 4260371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 4270371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Integer) impl.getOption(SocketOptions.SO_SNDBUF); 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 431a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@link SocketOptions#SO_TIMEOUT receive timeout}. 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized int getSoTimeout() throws SocketException { 4340371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 4350371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Integer) impl.getOption(SocketOptions.SO_TIMEOUT); 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 439a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@code SocketOptions#TCP_NODELAY} setting. 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getTcpNoDelay() throws SocketException { 4420371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 4430371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Boolean) impl.getOption(SocketOptions.TCP_NODELAY); 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 447a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#SO_KEEPALIVE} option. 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 4490371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void setKeepAlive(boolean keepAlive) throws SocketException { 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (impl != null) { 4510371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 4520371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes impl.setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(keepAlive)); 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the internal factory for creating socket implementations. This may 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only be executed once during the lifetime of the application. 459f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param fac 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the socket implementation factory to be set. 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the factory has been already set. 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static synchronized void setSocketImplFactory(SocketImplFactory fac) 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (factory != null) { 468b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Factory already set"); 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project factory = fac; 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 474a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#SO_SNDBUF send buffer size}. 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void setSendBufferSize(int size) throws SocketException { 4770371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (size < 1) { 479b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("size < 1"); 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size)); 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 485a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#SO_SNDBUF receive buffer size}. 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 487b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes public synchronized void setReceiveBufferSize(int size) throws SocketException { 4880371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (size < 1) { 490b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("size < 1"); 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size)); 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 496a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#SO_LINGER linger} timeout in seconds. 497a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * If {@code on} is false, {@code timeout} is irrelevant. 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setSoLinger(boolean on, int timeout) throws SocketException { 5000371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 5010371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // The RI explicitly guarantees this idiocy in the SocketOptions.setOption documentation. 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (on && timeout < 0) { 503b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("timeout < 0"); 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (on) { 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.setOption(SocketOptions.SO_LINGER, Integer.valueOf(timeout)); 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.setOption(SocketOptions.SO_LINGER, Boolean.FALSE); 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 513a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#SO_TIMEOUT read timeout} in milliseconds. 514a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Use 0 for no timeout. 515a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * To take effect, this option must be set before the blocking method was called. 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public synchronized void setSoTimeout(int timeout) throws SocketException { 5180371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (timeout < 0) { 520b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("timeout < 0"); 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout)); 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 526a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#TCP_NODELAY} option. 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setTcpNoDelay(boolean on) throws SocketException { 5290371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on)); 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a stream socket, binds it to the nominated local address/port, 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * then connects it to the nominated destination address/port. 536f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstAddress 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the destination host address. 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dstPort 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the destination host. 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param localAddress 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the address on the local machine to bind. 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param localPort 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the port on the local machine to bind. 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * thrown if an error occurs during the bind or connect 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * operations. 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 5490371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes private void startupSocket(InetAddress dstAddress, int dstPort, 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetAddress localAddress, int localPort, boolean streaming) 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (localPort < 0 || localPort > 65535) { 554b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Local port out of range: " + localPort); 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 5578cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetAddress addr = localAddress == null ? Inet4Address.ANY : localAddress; 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.create(streaming); 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isCreated = true; 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5620917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes if (!streaming || !usingSocks()) { 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.bind(addr, localPort); 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isBound = true; 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.connect(dstAddress, dstPort); 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isConnected = true; 5688cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes cacheLocalAddress(); 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.close(); 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 5760917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes private boolean usingSocks() { 5770917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes return proxy != null && proxy.type() == Proxy.Type.SOCKS; 5780917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes } 5790917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a {@code String} containing a concise, human-readable description of the 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket. 583f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the textual representation of this socket. 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected()) { 589f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return "Socket[unconnected]"; 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return impl.toString(); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the input stream of this socket. Any further data sent to this 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * socket will be discarded. Reading from this socket after this method has 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * been called will return the value {@code EOF}. 598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while closing the socket input stream. 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the input stream is already closed. 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownInput() throws IOException { 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isInputShutdown()) { 606b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Socket input is shutdown"); 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 6080371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(false); 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.shutdownInput(); 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isInputShutdown = true; 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes the output stream of this socket. All buffered data will be sent 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * followed by the termination sequence. Writing to the closed output stream 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * will cause an {@code IOException}. 617f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while closing the socket output stream. 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the output stream is already closed. 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void shutdownOutput() throws IOException { 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOutputShutdown()) { 625b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Socket output is shutdown"); 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 6270371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(false); 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.shutdownOutput(); 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isOutputShutdown = true; 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Checks whether the socket is closed, and throws an exception. Otherwise 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * creates the underlying SocketImpl. 635f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SocketException 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the socket is closed. 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6390371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes private void checkOpenAndCreate(boolean create) throws SocketException { 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isClosed()) { 641b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Socket is closed"); 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!create) { 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected()) { 645b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Socket is not connected"); 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // a connected socket must be created 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * return directly to fix a possible bug, if !create, should return 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * here 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isCreated) { 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isCreated) { 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.create(true); 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SocketException e) { 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SocketException(e.toString()); 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isCreated = true; 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 674a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns the local address and port of this socket as a SocketAddress or 675a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * null if the socket is unbound. This is useful on multihomed 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * hosts. 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SocketAddress getLocalSocketAddress() { 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isBound()) { 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new InetSocketAddress(getLocalAddress(), getLocalPort()); 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 686a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns the remote address and port of this socket as a {@code 687a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * SocketAddress} or null if the socket is not connected. 688f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the remote socket address and port. 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SocketAddress getRemoteSocketAddress() { 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isConnected()) { 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new InetSocketAddress(getInetAddress(), getPort()); 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this socket is bound to a local address and port. 700f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the socket is bound to a local address, {@code 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * false} otherwise. 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isBound() { 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isBound; 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this socket is connected to a remote host. 710f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the socket is connected, {@code false} otherwise. 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isConnected() { 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isConnected; 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this socket is closed. 719f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the socket is closed, {@code false} otherwise. 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isClosed() { 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isClosed; 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Binds this socket to the given local host address and port specified by 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the SocketAddress {@code localAddr}. If {@code localAddr} is set to 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null}, this socket will be bound to an available local address on 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * any free port. 731f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param localAddr 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the specific address and port on the local machine to bind to. 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given SocketAddress is invalid or not supported. 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the socket is already bound or an error occurs while 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * binding. 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void bind(SocketAddress localAddr) throws IOException { 7410371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isBound()) { 743b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new BindException("Socket is already bound"); 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int port = 0; 747051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti InetAddress addr = Inet4Address.ANY; 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (localAddr != null) { 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(localAddr instanceof InetSocketAddress)) { 750b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Local address not an InetSocketAddress: " + 751b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes localAddr.getClass()); 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetSocketAddress inetAddr = (InetSocketAddress) localAddr; 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((addr = inetAddr.getAddress()) == null) { 755c61ad82613eb264cbf93e91519b0c061d11b3c2dElliott Hughes throw new UnknownHostException("Host is unresolved: " + inetAddr.getHostName()); 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project port = inetAddr.getPort(); 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (this) { 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.bind(addr, port); 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isBound = true; 7648cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes cacheLocalAddress(); 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.close(); 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Connects this socket to the given remote host address and port specified 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by the SocketAddress {@code remoteAddr}. 775f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param remoteAddr 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the address and port of the remote host to connect to. 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given SocketAddress is invalid or not supported. 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the socket is already connected or an error occurs while 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connecting. 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void connect(SocketAddress remoteAddr) throws IOException { 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project connect(remoteAddr, 0); 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Connects this socket to the given remote host address and port specified 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * by the SocketAddress {@code remoteAddr} with the specified timeout. The 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connecting method will block until the connection is established or an 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * error occurred. 793f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param remoteAddr 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the address and port of the remote host to connect to. 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param timeout 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the timeout value in milliseconds or {@code 0} for an infinite 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * timeout. 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the given SocketAddress is invalid or not supported or the 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * timeout value is negative. 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the socket is already connected or an error occurs while 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * connecting. 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 8068cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public void connect(SocketAddress remoteAddr, int timeout) throws IOException { 8070371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (timeout < 0) { 809b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("timeout < 0"); 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isConnected()) { 812b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new SocketException("Already connected"); 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (remoteAddr == null) { 815b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("remoteAddr == null"); 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(remoteAddr instanceof InetSocketAddress)) { 819b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Remote address not an InetSocketAddress: " + 820b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes remoteAddr.getClass()); 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr; 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project InetAddress addr; 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((addr = inetAddr.getAddress()) == null) { 825c61ad82613eb264cbf93e91519b0c061d11b3c2dElliott Hughes throw new UnknownHostException("Host is unresolved: " + inetAddr.getHostName()); 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int port = inetAddr.getPort(); 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkDestination(addr, port); 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (connectLock) { 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isBound()) { 8338cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // socket already created at this point by earlier call or 8340371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // checkOpenAndCreate this caused us to lose socket 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // options on create 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // impl.create(true); 8370917c4a9d5d0115950450cdd0bb46e43a48da5dbElliott Hughes if (!usingSocks()) { 838051128862ae7c5c031b8ddb763848ed264a63746Lorenzo Colitti impl.bind(Inet4Address.ANY, 0); 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isBound = true; 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.connect(remoteAddr, timeout); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isConnected = true; 8448cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes cacheLocalAddress(); 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.close(); 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether the incoming channel of the socket has already been 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * closed. 855f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if reading from this socket is not possible anymore, 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isInputShutdown() { 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isInputShutdown; 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 864f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Returns whether the outgoing channel of the socket has already been 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * closed. 866f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if writing to this socket is not possible anymore, 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isOutputShutdown() { 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isOutputShutdown; 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 875a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#SO_REUSEADDR} option. 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setReuseAddress(boolean reuse) throws SocketException { 8780371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 8790371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(reuse)); 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 883a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@link SocketOptions#SO_REUSEADDR} setting. 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getReuseAddress() throws SocketException { 8860371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 8870371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Boolean) impl.getOption(SocketOptions.SO_REUSEADDR); 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 891a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#SO_OOBINLINE} option. 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setOOBInline(boolean oobinline) throws SocketException { 8940371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 8950371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes impl.setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(oobinline)); 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 899a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Returns this socket's {@link SocketOptions#SO_OOBINLINE} setting. 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getOOBInline() throws SocketException { 9020371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 9030371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Boolean) impl.getOption(SocketOptions.SO_OOBINLINE); 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 907a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * Sets this socket's {@link SocketOptions#IP_TOS} value for every packet sent by this socket. 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setTrafficClass(int value) throws SocketException { 9100371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (value < 0 || value > 255) { 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.setOption(SocketOptions.IP_TOS, Integer.valueOf(value)); 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 9182cd82d7111f68ff63145ef7c393bf1479ff06223Elliott Hughes * Returns this socket's {@see SocketOptions#IP_TOS} setting. 919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getTrafficClass() throws SocketException { 9210371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes checkOpenAndCreate(true); 9220371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes return (Integer) impl.getOption(SocketOptions.IP_TOS); 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sends the given single byte data which is represented by the lowest octet 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of {@code value} as "TCP urgent data". 928f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the byte of urgent data to be sent. 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs while sending urgent data. 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sendUrgentData(int value) throws IOException { 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project impl.sendUrgentData(value); 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the appropriate flags for a socket created by {@code 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ServerSocket.accept()}. 941f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ServerSocket#implAccept 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void accepted() { 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isCreated = isBound = isConnected = true; 9468cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes cacheLocalAddress(); 9478cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 9488cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 9498cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes private void cacheLocalAddress() { 9500b736ebc4efef64f2db1999aea90297ad8196146Elliott Hughes this.localAddress = IoBridge.getSocketLocalAddress(impl.fd); 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 9540d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * Returns this socket's {@code SocketChannel}, if one exists. A channel is 9550d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * available only if this socket wraps a channel. (That is, you can go from a 9560d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * channel to a socket and back again, but you can't go from an arbitrary socket to a channel.) 9570d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * In practice, this means that the socket must have been created by 9580d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * {@link java.nio.channels.ServerSocketChannel#accept} or 9590d93c38cc3c7a5001aece8a18cafc6d1fc7551f3Elliott Hughes * {@link java.nio.channels.SocketChannel#open}. 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SocketChannel getChannel() { 962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 966dc33f53f38600943c84146320c748e3c46fd2e7bElliott Hughes * @hide internal use only 967dc33f53f38600943c84146320c748e3c46fd2e7bElliott Hughes */ 9683267a46b52d848e1e9e20c226512688f0c50d4c3Jeff Sharkey public FileDescriptor getFileDescriptor$() { 969dc33f53f38600943c84146320c748e3c46fd2e7bElliott Hughes return impl.fd; 970dc33f53f38600943c84146320c748e3c46fd2e7bElliott Hughes } 971dc33f53f38600943c84146320c748e3c46fd2e7bElliott Hughes 972dc33f53f38600943c84146320c748e3c46fd2e7bElliott Hughes /** 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets performance preferences for connectionTime, latency and bandwidth. 974a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * 975a9c6c9013b08934867f71b69a90efce0c1b66918Elliott Hughes * <p>This method does currently nothing. 976f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param connectionTime 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the value representing the importance of a short connecting 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * time. 980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param latency 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the value representing the importance of low latency. 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param bandwidth 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the value representing the importance of high bandwidth. 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 9850371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Our socket implementation only provide one protocol: TCP/IP, so 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // we do nothing for this method 988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 990