SocketTest.java revision 4557728efb66c455a52b7669a8eefef7a9e54854
1a9a57f2581773484d13e160fd3407692e825971aElliott Hughes/* 2a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Copyright (C) 2009 The Android Open Source Project 3f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 4a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * you may not use this file except in compliance with the License. 6a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * You may obtain a copy of the License at 7f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 8a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 10a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Unless required by applicable law or agreed to in writing, software 11a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * See the License for the specific language governing permissions and 14a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * limitations under the License. 15a9a57f2581773484d13e160fd3407692e825971aElliott Hughes */ 16a9a57f2581773484d13e160fd3407692e825971aElliott Hughes 174557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonpackage libcore.java.net; 18a9a57f2581773484d13e160fd3407692e825971aElliott Hughes 190371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughesimport java.io.IOException; 200371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughesimport java.io.InputStream; 210371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughesimport java.io.OutputStream; 224557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.ConnectException; 234557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.InetAddress; 244557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.InetSocketAddress; 254557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.ServerSocket; 264557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.Socket; 274557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.SocketAddress; 284557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.SocketException; 294557728efb66c455a52b7669a8eefef7a9e54854Jesse Wilsonimport java.net.SocketImpl; 308cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughesimport java.nio.channels.ServerSocketChannel; 318cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughesimport java.nio.channels.SocketChannel; 328cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 33a9a57f2581773484d13e160fd3407692e825971aElliott Hughespublic class SocketTest extends junit.framework.TestCase { 34a9a57f2581773484d13e160fd3407692e825971aElliott Hughes /** 35a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * Our getLocalAddress and getLocalPort currently use getsockname(3). 36a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * This means they give incorrect results on closed sockets (as well 37a9a57f2581773484d13e160fd3407692e825971aElliott Hughes * as requiring an unnecessary call into native code). 38a9a57f2581773484d13e160fd3407692e825971aElliott Hughes */ 39a9a57f2581773484d13e160fd3407692e825971aElliott Hughes public void test_getLocalAddress_after_close() throws Exception { 40a9a57f2581773484d13e160fd3407692e825971aElliott Hughes Socket s = new Socket(); 41a9a57f2581773484d13e160fd3407692e825971aElliott Hughes try { 42a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // Bind to an ephemeral local port. 43a9a57f2581773484d13e160fd3407692e825971aElliott Hughes s.bind(new InetSocketAddress("localhost", 0)); 44a9a57f2581773484d13e160fd3407692e825971aElliott Hughes assertTrue(s.getLocalAddress().isLoopbackAddress()); 45a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // What local port did we get? 46a9a57f2581773484d13e160fd3407692e825971aElliott Hughes int localPort = s.getLocalPort(); 47a9a57f2581773484d13e160fd3407692e825971aElliott Hughes assertTrue(localPort > 0); 48a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // Now close the socket... 49a9a57f2581773484d13e160fd3407692e825971aElliott Hughes s.close(); 50a9a57f2581773484d13e160fd3407692e825971aElliott Hughes // The RI returns the ANY address but the original local port after close. 51a9a57f2581773484d13e160fd3407692e825971aElliott Hughes assertTrue(s.getLocalAddress().isAnyLocalAddress()); 52a9a57f2581773484d13e160fd3407692e825971aElliott Hughes assertEquals(localPort, s.getLocalPort()); 53a9a57f2581773484d13e160fd3407692e825971aElliott Hughes } finally { 54a9a57f2581773484d13e160fd3407692e825971aElliott Hughes s.close(); 55a9a57f2581773484d13e160fd3407692e825971aElliott Hughes } 56a9a57f2581773484d13e160fd3407692e825971aElliott Hughes } 57ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes 58ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes // http://code.google.com/p/android/issues/detail?id=7935 59ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes public void test_newSocket_connection_refused() throws Exception { 60ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes try { 61ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes new Socket("localhost", 80); 62ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes fail("connection should have been refused"); 63ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes } catch (ConnectException expected) { 64ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes } 65ad4718b11db66d197b14cd0ec3ed17905bbedd34Elliott Hughes } 668cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 678cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // http://code.google.com/p/android/issues/detail?id=3123 688cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // http://code.google.com/p/android/issues/detail?id=1933 698cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public void test_socketLocalAndRemoteAddresses() throws Exception { 708cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes checkSocketLocalAndRemoteAddresses(false); 718cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes checkSocketLocalAndRemoteAddresses(true); 728cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 738cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 748cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes public void checkSocketLocalAndRemoteAddresses(boolean setOptions) throws Exception { 758cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetAddress host = InetAddress.getLocalHost(); 768cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 778cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // Open a local server port. 788cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ServerSocketChannel ssc = ServerSocketChannel.open(); 798cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress listenAddr = new InetSocketAddress(host, 0); 808cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ssc.socket().bind(listenAddr, 0); 818cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ServerSocket ss = ssc.socket(); 828cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 838cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes // Open a socket to the local port. 848cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes SocketChannel out = SocketChannel.open(); 858cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.configureBlocking(false); 868cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes if (setOptions) { 878cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.socket().setTcpNoDelay(false); 888cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 898cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress addr = new InetSocketAddress(host, ssc.socket().getLocalPort()); 908cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.connect(addr); 918cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes while (!out.finishConnect()) { 928cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes Thread.sleep(1); 938cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 948cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 958cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes SocketChannel in = ssc.accept(); 968cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes if (setOptions) { 978cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes in.socket().setTcpNoDelay(false); 988cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 998cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1008cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress outRemoteAddress = (InetSocketAddress) out.socket().getRemoteSocketAddress(); 1018cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress outLocalAddress = (InetSocketAddress) out.socket().getLocalSocketAddress(); 1028cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress inLocalAddress = (InetSocketAddress) in.socket().getLocalSocketAddress(); 1038cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes InetSocketAddress inRemoteAddress = (InetSocketAddress) in.socket().getRemoteSocketAddress(); 1048cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("inLocalAddress: " + inLocalAddress); 1058cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("inRemoteAddress: " + inRemoteAddress); 1068cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("outLocalAddress: " + outLocalAddress); 1078cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes System.err.println("outRemoteAddress: " + outRemoteAddress); 1088cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1098cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(outRemoteAddress.getPort(), ss.getLocalPort()); 1108cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inLocalAddress.getPort(), ss.getLocalPort()); 1118cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inRemoteAddress.getPort(), outLocalAddress.getPort()); 1128cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1138cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inLocalAddress.getAddress(), ss.getInetAddress()); 1148cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(inRemoteAddress.getAddress(), ss.getInetAddress()); 1158cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(outLocalAddress.getAddress(), ss.getInetAddress()); 1168cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(outRemoteAddress.getAddress(), ss.getInetAddress()); 1178cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1188cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes in.close(); 1198cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes out.close(); 1208cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes ssc.close(); 1218cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1228cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertNull(in.socket().getRemoteSocketAddress()); 1238cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertNull(out.socket().getRemoteSocketAddress()); 1248cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes 1258cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes assertEquals(in.socket().getLocalSocketAddress(), ss.getLocalSocketAddress()); 1268cc54e9f098c4f299d2b88bb2b9110ce44354ed7Elliott Hughes } 1270371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1280371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // SocketOptions.setOption has weird behavior for setSoLinger/SO_LINGER. 1290371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // This test ensures we do what the RI does. 1300371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void test_SocketOptions_setOption() throws Exception { 1310371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes class MySocketImpl extends SocketImpl { 1320371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public int option; 1330371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public Object value; 1340371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1350371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public boolean createCalled; 1360371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public boolean createStream; 1370371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1380371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public MySocketImpl() { super(); } 1390371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void accept(SocketImpl arg0) throws IOException { } 1400371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected int available() throws IOException { return 0; } 1410371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void bind(InetAddress arg0, int arg1) throws IOException { } 1420371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void close() throws IOException { } 1430371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void connect(String arg0, int arg1) throws IOException { } 1440371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void connect(InetAddress arg0, int arg1) throws IOException { } 1450371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void connect(SocketAddress arg0, int arg1) throws IOException { } 1460371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected InputStream getInputStream() throws IOException { return null; } 1470371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected OutputStream getOutputStream() throws IOException { return null; } 1480371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void listen(int arg0) throws IOException { } 1490371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void sendUrgentData(int arg0) throws IOException { } 1500371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public Object getOption(int arg0) throws SocketException { return null; } 1510371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1520371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes @Override protected void create(boolean isStream) throws IOException { 1530371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.createCalled = true; 1540371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.createStream = isStream; 1550371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1560371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1570371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void setOption(int option, Object value) throws SocketException { 1580371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.option = option; 1590371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes this.value = value; 1600371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1610371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1620371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1630371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes class MySocket extends Socket { 1640371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public MySocket(SocketImpl impl) throws SocketException { 1650371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes super(impl); 1660371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1670371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1680371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1690371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes MySocketImpl impl = new MySocketImpl(); 1700371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes Socket s = new MySocket(impl); 1710371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1720371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // Check that, as per the SocketOptions.setOption documentation, we pass false rather 1730371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // than -1 to the SocketImpl when setSoLinger is called with the first argument false. 1740371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(false, -1); 1750371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Boolean.FALSE, (Boolean) impl.value); 1760371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // We also check that SocketImpl.create was called. SocketChannelImpl.SocketAdapter 1770371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // subclasses Socket, and whether or not to call SocketImpl.create is the main behavioral 1780371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // difference. 1790371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(true, impl.createCalled); 1800371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(false, 0); 1810371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Boolean.FALSE, (Boolean) impl.value); 1820371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(false, 1); 1830371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Boolean.FALSE, (Boolean) impl.value); 1840371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1850371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes // Check that otherwise, we pass down an Integer. 1860371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(true, 0); 1870371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Integer.valueOf(0), (Integer) impl.value); 1880371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setSoLinger(true, 1); 1890371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(Integer.valueOf(1), (Integer) impl.value); 1900371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 1910371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes 1920371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes public void test_setTrafficClass() throws Exception { 1930371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes Socket s = new Socket(); 1940371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes s.setTrafficClass(123); 1950371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes assertEquals(123, s.getTrafficClass()); 1960371d85fa3ecb5f162d107cdbff0a99cd987fdccElliott Hughes } 197a9a57f2581773484d13e160fd3407692e825971aElliott Hughes} 198