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