1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package libcore.java.nio.channels; 18 19import java.io.IOException; 20import java.net.InetAddress; 21import java.net.InetSocketAddress; 22import java.net.NetworkInterface; 23import java.net.ServerSocket; 24import java.net.SocketException; 25import java.net.StandardSocketOptions; 26import java.nio.channels.AlreadyBoundException; 27import java.nio.channels.ClosedChannelException; 28import java.nio.channels.ServerSocketChannel; 29import java.nio.channels.SocketChannel; 30import java.nio.channels.UnresolvedAddressException; 31import java.nio.channels.UnsupportedAddressTypeException; 32import java.util.Enumeration; 33import java.util.Set; 34 35public class ServerSocketChannelTest extends junit.framework.TestCase { 36 // http://code.google.com/p/android/issues/detail?id=16579 37 public void testNonBlockingAccept() throws Exception { 38 ServerSocketChannel ssc = ServerSocketChannel.open(); 39 try { 40 ssc.configureBlocking(false); 41 ssc.socket().bind(null); 42 // Should return immediately, since we're non-blocking. 43 assertNull(ssc.accept()); 44 } finally { 45 ssc.close(); 46 } 47 } 48 49 /** Checks the state of the ServerSocketChannel and associated ServerSocket after open() */ 50 public void test_open_initialState() throws Exception { 51 ServerSocketChannel ssc = ServerSocketChannel.open(); 52 try { 53 assertNull(ssc.socket().getLocalSocketAddress()); 54 55 ServerSocket socket = ssc.socket(); 56 assertFalse(socket.isBound()); 57 assertFalse(socket.isClosed()); 58 assertEquals(-1, socket.getLocalPort()); 59 assertNull(socket.getLocalSocketAddress()); 60 assertNull(socket.getInetAddress()); 61 assertTrue(socket.getReuseAddress()); 62 63 assertSame(ssc, socket.getChannel()); 64 } finally { 65 ssc.close(); 66 } 67 } 68 69 public void test_bind_unresolvedAddress() throws IOException { 70 ServerSocketChannel ssc = ServerSocketChannel.open(); 71 try { 72 ssc.socket().bind(new InetSocketAddress("unresolvedname", 31415)); 73 fail(); 74 } catch (SocketException expected) { 75 } 76 77 assertNull(ssc.socket().getLocalSocketAddress()); 78 assertTrue(ssc.isOpen()); 79 80 ssc.close(); 81 } 82 83 public void test_bind_nullBindsToAll() throws Exception { 84 ServerSocketChannel ssc = ServerSocketChannel.open(); 85 ssc.socket().bind(null); 86 InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress(); 87 assertTrue(boundAddress.getAddress().isAnyLocalAddress()); 88 assertFalse(boundAddress.getAddress().isLinkLocalAddress()); 89 assertFalse(boundAddress.getAddress().isLoopbackAddress()); 90 91 // Attempt to connect to the "any" address. 92 assertTrue(canConnect(boundAddress)); 93 94 // Go through all local IPs and try to connect to each in turn - all should succeed. 95 Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 96 while (interfaces.hasMoreElements()) { 97 NetworkInterface nic = interfaces.nextElement(); 98 Enumeration<InetAddress> inetAddresses = nic.getInetAddresses(); 99 while (inetAddresses.hasMoreElements()) { 100 InetSocketAddress address = 101 new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort()); 102 assertTrue(canConnect(address)); 103 } 104 } 105 106 ssc.close(); 107 } 108 109 public void test_bind_loopback() throws Exception { 110 ServerSocketChannel ssc = ServerSocketChannel.open(); 111 ssc.socket().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); 112 InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress(); 113 assertFalse(boundAddress.getAddress().isAnyLocalAddress()); 114 assertFalse(boundAddress.getAddress().isLinkLocalAddress()); 115 assertTrue(boundAddress.getAddress().isLoopbackAddress()); 116 117 // Attempt to connect to the "loopback" address. Note: There can be several loopback 118 // addresses, such as 127.0.0.1 (IPv4) and 0:0:0:0:0:0:0:1 (IPv6) and only one will be 119 // bound. 120 InetSocketAddress loopbackAddress = 121 new InetSocketAddress(InetAddress.getLoopbackAddress(), boundAddress.getPort()); 122 assertTrue(canConnect(loopbackAddress)); 123 124 // Go through all local IPs and try to connect to each in turn - all should fail except 125 // for the loopback. 126 Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 127 while (interfaces.hasMoreElements()) { 128 NetworkInterface nic = interfaces.nextElement(); 129 Enumeration<InetAddress> inetAddresses = nic.getInetAddresses(); 130 while (inetAddresses.hasMoreElements()) { 131 InetSocketAddress address = 132 new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort()); 133 if (!address.equals(loopbackAddress)) { 134 assertFalse(canConnect(address)); 135 } 136 } 137 } 138 139 ssc.close(); 140 } 141 142 public void test_bind$SocketAddress() throws IOException { 143 ServerSocketChannel ssc = ServerSocketChannel.open(); 144 ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); 145 assertEquals(InetAddress.getLoopbackAddress(), 146 ((InetSocketAddress)(ssc.getLocalAddress())).getAddress()); 147 assertTrue(((InetSocketAddress)(ssc.getLocalAddress())).getPort() > 0); 148 149 try { 150 ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 151 ((InetSocketAddress)(ssc.getLocalAddress())).getPort())); 152 fail(); 153 } catch (AlreadyBoundException expected) { 154 } 155 156 try { 157 ServerSocketChannel ssc1 = ServerSocketChannel.open(); 158 ssc1.bind(new InetSocketAddress("1.1.1.1.1.1.1", 0)); 159 fail(); 160 } catch (UnresolvedAddressException expected) { 161 } 162 163 ssc.close(); 164 try { 165 ssc.bind(new InetSocketAddress("1.1.1.1.1.1.1", 0)); 166 fail(); 167 } catch (ClosedChannelException expected) { 168 } 169 } 170 171 public void test_setOption() throws Exception { 172 ServerSocketChannel sc = ServerSocketChannel.open(); 173 sc.setOption(StandardSocketOptions.SO_REUSEADDR, true); 174 175 // Assert that we can read back the option from the channel... 176 assertTrue(sc.getOption(StandardSocketOptions.SO_REUSEADDR)); 177 178 sc.setOption(StandardSocketOptions.SO_REUSEADDR, false); 179 180 // Assert that we can read back the option from the channel... 181 assertEquals(false, (boolean)sc.getOption(StandardSocketOptions.SO_REUSEADDR)); 182 183 sc.setOption(StandardSocketOptions.SO_RCVBUF, 1100); 184 assertTrue(1100 <= sc.getOption(StandardSocketOptions.SO_RCVBUF)); 185 186 sc.close(); 187 try { 188 sc.setOption(StandardSocketOptions.SO_RCVBUF, 2000); 189 fail(); 190 } catch (ClosedChannelException expected) { 191 } 192 } 193 194 private static boolean canConnect(InetSocketAddress address) { 195 try { 196 SocketChannel socketChannel = SocketChannel.open(address); 197 socketChannel.close(); 198 return true; 199 } catch (IOException e) { 200 return false; 201 } 202 } 203} 204