ServerSocketChannelTest.java revision ff81b740a338ba964e0ba1c40d925fb2ceb37bf2
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.SocketOption; 25import java.net.StandardSocketOptions; 26import java.nio.channels.ClosedChannelException; 27import java.nio.channels.ServerSocketChannel; 28import java.nio.channels.SocketChannel; 29import java.util.Enumeration; 30import java.util.Set; 31 32public class ServerSocketChannelTest extends junit.framework.TestCase { 33 // http://code.google.com/p/android/issues/detail?id=16579 34 public void testNonBlockingAccept() throws Exception { 35 ServerSocketChannel ssc = ServerSocketChannel.open(); 36 try { 37 ssc.configureBlocking(false); 38 ssc.bind(null); 39 // Should return immediately, since we're non-blocking. 40 assertNull(ssc.accept()); 41 } finally { 42 ssc.close(); 43 } 44 } 45 46 /** Checks the state of the ServerSocketChannel and associated ServerSocket after open() */ 47 public void test_open_initialState() throws Exception { 48 ServerSocketChannel ssc = ServerSocketChannel.open(); 49 try { 50 assertNull(ssc.getLocalAddress()); 51 52 ServerSocket socket = ssc.socket(); 53 assertFalse(socket.isBound()); 54 assertFalse(socket.isClosed()); 55 assertEquals(-1, socket.getLocalPort()); 56 assertNull(socket.getLocalSocketAddress()); 57 assertNull(socket.getInetAddress()); 58 assertTrue(socket.getReuseAddress()); 59 60 assertSame(ssc, socket.getChannel()); 61 } finally { 62 ssc.close(); 63 } 64 } 65 66 public void test_bind_nullBindsToAll() throws Exception { 67 ServerSocketChannel ssc = ServerSocketChannel.open(); 68 ssc.bind(null); 69 InetSocketAddress boundAddress = (InetSocketAddress) ssc.getLocalAddress(); 70 assertTrue(boundAddress.getAddress().isAnyLocalAddress()); 71 assertFalse(boundAddress.getAddress().isLinkLocalAddress()); 72 assertFalse(boundAddress.getAddress().isLoopbackAddress()); 73 74 // Attempt to connect to the "any" address. 75 assertTrue(canConnect(boundAddress)); 76 77 // Go through all local IPs and try to connect to each in turn - all should succeed. 78 Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 79 while (interfaces.hasMoreElements()) { 80 NetworkInterface nic = interfaces.nextElement(); 81 Enumeration<InetAddress> inetAddresses = nic.getInetAddresses(); 82 while (inetAddresses.hasMoreElements()) { 83 InetSocketAddress address = 84 new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort()); 85 assertTrue(canConnect(address)); 86 } 87 } 88 89 ssc.close(); 90 } 91 92 public void test_bind_loopback() throws Exception { 93 ServerSocketChannel ssc = ServerSocketChannel.open(); 94 ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); 95 InetSocketAddress boundAddress = (InetSocketAddress) ssc.getLocalAddress(); 96 assertFalse(boundAddress.getAddress().isAnyLocalAddress()); 97 assertFalse(boundAddress.getAddress().isLinkLocalAddress()); 98 assertTrue(boundAddress.getAddress().isLoopbackAddress()); 99 100 // Attempt to connect to the "loopback" address. Note: There can be several loopback 101 // addresses, such as 127.0.0.1 (IPv4) and 0:0:0:0:0:0:0:1 (IPv6) and only one will be 102 // bound. 103 InetSocketAddress loopbackAddress = 104 new InetSocketAddress(InetAddress.getLoopbackAddress(), boundAddress.getPort()); 105 assertTrue(canConnect(loopbackAddress)); 106 107 // Go through all local IPs and try to connect to each in turn - all should fail except 108 // for the loopback. 109 Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 110 while (interfaces.hasMoreElements()) { 111 NetworkInterface nic = interfaces.nextElement(); 112 Enumeration<InetAddress> inetAddresses = nic.getInetAddresses(); 113 while (inetAddresses.hasMoreElements()) { 114 InetSocketAddress address = 115 new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort()); 116 if (!address.equals(loopbackAddress)) { 117 assertFalse(canConnect(address)); 118 } 119 } 120 } 121 122 ssc.close(); 123 } 124 125 private static boolean canConnect(InetSocketAddress address) { 126 try { 127 SocketChannel socketChannel = SocketChannel.open(address); 128 socketChannel.close(); 129 return true; 130 } catch (IOException e) { 131 return false; 132 } 133 } 134 135 public void test_supportedOptions() throws Exception { 136 ServerSocketChannel ssc = ServerSocketChannel.open(); 137 Set<SocketOption<?>> options = ssc.supportedOptions(); 138 139 // Probe some values. This is not intended to be complete. 140 assertTrue(options.contains(StandardSocketOptions.SO_REUSEADDR)); 141 assertFalse(options.contains(StandardSocketOptions.IP_MULTICAST_TTL)); 142 } 143 144 public void test_getOption_unsupportedOption() throws Exception { 145 ServerSocketChannel ssc = ServerSocketChannel.open(); 146 try { 147 ssc.getOption(StandardSocketOptions.IP_MULTICAST_TTL); 148 fail(); 149 } catch (UnsupportedOperationException expected) {} 150 151 ssc.close(); 152 } 153 154 public void test_getOption_afterClose() throws Exception { 155 ServerSocketChannel ssc = ServerSocketChannel.open(); 156 ssc.close(); 157 158 try { 159 ssc.getOption(StandardSocketOptions.SO_RCVBUF); 160 fail(); 161 } catch (ClosedChannelException expected) {} 162 } 163 164 public void test_setOption_afterClose() throws Exception { 165 ServerSocketChannel ssc = ServerSocketChannel.open(); 166 ssc.close(); 167 168 try { 169 ssc.setOption(StandardSocketOptions.SO_RCVBUF, 1234); 170 fail(); 171 } catch (ClosedChannelException expected) {} 172 } 173 174 public void test_getOption_SO_RCVBUF_defaults() throws Exception { 175 ServerSocketChannel ssc = ServerSocketChannel.open(); 176 177 int value = ssc.getOption(StandardSocketOptions.SO_RCVBUF); 178 assertTrue(value > 0); 179 assertEquals(value, ssc.socket().getReceiveBufferSize()); 180 181 ssc.close(); 182 } 183 184 public void test_setOption_SO_RCVBUF_afterOpen() throws Exception { 185 ServerSocketChannel ssc = ServerSocketChannel.open(); 186 187 trySetReceiveBufferSizeOption(ssc); 188 189 ssc.close(); 190 } 191 192 private static void trySetReceiveBufferSizeOption(ServerSocketChannel ssc) throws IOException { 193 int initialValue = ssc.getOption(StandardSocketOptions.SO_RCVBUF); 194 try { 195 ssc.setOption(StandardSocketOptions.SO_RCVBUF, -1); 196 fail(); 197 } catch (IllegalArgumentException expected) {} 198 int actualValue = ssc.getOption(StandardSocketOptions.SO_RCVBUF); 199 assertEquals(initialValue, actualValue); 200 assertEquals(initialValue, ssc.socket().getReceiveBufferSize()); 201 202 int newBufferSize = initialValue - 1; 203 ssc.setOption(StandardSocketOptions.SO_RCVBUF, newBufferSize); 204 actualValue = ssc.getOption(StandardSocketOptions.SO_RCVBUF); 205 // The Linux Kernel actually doubles the value it is given and may choose to ignore it. 206 // This assertion may be brittle. 207 assertTrue(actualValue != initialValue); 208 assertEquals(actualValue, ssc.socket().getReceiveBufferSize()); 209 } 210 211 public void test_getOption_SO_REUSEADDR_defaults() throws Exception { 212 ServerSocketChannel ssc = ServerSocketChannel.open(); 213 214 boolean value = ssc.getOption(StandardSocketOptions.SO_REUSEADDR); 215 assertTrue(value); 216 assertTrue(ssc.socket().getReuseAddress()); 217 218 ssc.close(); 219 } 220 221 public void test_setOption_SO_REUSEADDR_afterOpen() throws Exception { 222 ServerSocketChannel ssc = ServerSocketChannel.open(); 223 224 boolean initialValue = ssc.getOption(StandardSocketOptions.SO_REUSEADDR); 225 ssc.setOption(StandardSocketOptions.SO_REUSEADDR, !initialValue); 226 assertEquals(!initialValue, (boolean) ssc.getOption(StandardSocketOptions.SO_REUSEADDR)); 227 assertEquals(!initialValue, ssc.socket().getReuseAddress()); 228 229 ssc.close(); 230 } 231 232} 233