ServerSocketChannelTest.java revision 63744c884dd4b4f4307f2b021fb894af164972af
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.nio.channels.ClosedChannelException;
26import java.nio.channels.ServerSocketChannel;
27import java.nio.channels.SocketChannel;
28import java.nio.channels.UnresolvedAddressException;
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.socket().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.socket().getLocalSocketAddress());
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_unresolvedAddress() throws IOException {
67        ServerSocketChannel ssc = ServerSocketChannel.open();
68        try {
69            ssc.socket().bind(new InetSocketAddress("unresolvedname", 31415));
70            fail();
71        } catch (SocketException expected) {
72        }
73
74        assertNull(ssc.socket().getLocalSocketAddress());
75        assertTrue(ssc.isOpen());
76
77        ssc.close();
78    }
79
80    public void test_bind_nullBindsToAll() throws Exception {
81        ServerSocketChannel ssc = ServerSocketChannel.open();
82        ssc.socket().bind(null);
83        InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
84        assertTrue(boundAddress.getAddress().isAnyLocalAddress());
85        assertFalse(boundAddress.getAddress().isLinkLocalAddress());
86        assertFalse(boundAddress.getAddress().isLoopbackAddress());
87
88        // Attempt to connect to the "any" address.
89        assertTrue(canConnect(boundAddress));
90
91        // Go through all local IPs and try to connect to each in turn - all should succeed.
92        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
93        while (interfaces.hasMoreElements()) {
94            NetworkInterface nic = interfaces.nextElement();
95            Enumeration<InetAddress> inetAddresses = nic.getInetAddresses();
96            while (inetAddresses.hasMoreElements()) {
97                InetSocketAddress address =
98                        new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort());
99                assertTrue(canConnect(address));
100            }
101        }
102
103        ssc.close();
104    }
105
106    public void test_bind_loopback() throws Exception {
107        ServerSocketChannel ssc = ServerSocketChannel.open();
108        ssc.socket().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
109        InetSocketAddress boundAddress = (InetSocketAddress) ssc.socket().getLocalSocketAddress();
110        assertFalse(boundAddress.getAddress().isAnyLocalAddress());
111        assertFalse(boundAddress.getAddress().isLinkLocalAddress());
112        assertTrue(boundAddress.getAddress().isLoopbackAddress());
113
114        // Attempt to connect to the "loopback" address. Note: There can be several loopback
115        // addresses, such as 127.0.0.1 (IPv4) and 0:0:0:0:0:0:0:1 (IPv6) and only one will be
116        // bound.
117        InetSocketAddress loopbackAddress =
118                new InetSocketAddress(InetAddress.getLoopbackAddress(), boundAddress.getPort());
119        assertTrue(canConnect(loopbackAddress));
120
121        // Go through all local IPs and try to connect to each in turn - all should fail except
122        // for the loopback.
123        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
124        while (interfaces.hasMoreElements()) {
125            NetworkInterface nic = interfaces.nextElement();
126            Enumeration<InetAddress> inetAddresses = nic.getInetAddresses();
127            while (inetAddresses.hasMoreElements()) {
128                InetSocketAddress address =
129                        new InetSocketAddress(inetAddresses.nextElement(), boundAddress.getPort());
130                if (!address.equals(loopbackAddress)) {
131                    assertFalse(canConnect(address));
132                }
133            }
134        }
135
136        ssc.close();
137    }
138
139    private static boolean canConnect(InetSocketAddress address) {
140        try {
141            SocketChannel socketChannel = SocketChannel.open(address);
142            socketChannel.close();
143            return true;
144        } catch (IOException e) {
145            return false;
146        }
147    }
148}
149