1/*
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/* @test
25 * @summary Test Selector with ServerSocketChannels
26 * @library ..
27 */
28
29import java.io.*;
30import java.net.*;
31import java.nio.*;
32import java.nio.channels.*;
33import java.nio.channels.spi.SelectorProvider;
34import java.util.*;
35
36
37public class BasicAccept {
38
39    static void server(ServerSocketChannel ssc) throws Exception {
40        Selector acceptSelector = Selector.open();
41        try {
42            ssc.configureBlocking(false);
43            SelectionKey acceptKey
44                = ssc.register(acceptSelector, SelectionKey.OP_ACCEPT);
45            for (;;) {
46                int n = acceptSelector.select();
47                if (Thread.interrupted())
48                    break;
49                if (n == 0)
50                    continue;
51                Set<SelectionKey> readyKeys = acceptSelector.selectedKeys();
52                Iterator<SelectionKey> i = readyKeys.iterator();
53                while (i.hasNext()) {
54                    SelectionKey sk = i.next();
55                    i.remove();
56                    ServerSocketChannel nextReady
57                        = (ServerSocketChannel)sk.channel();
58                    SocketChannel sc = nextReady.accept();
59                    ByteBuffer bb = ByteBuffer.wrap(new byte[] { 42 });
60                    sc.write(bb);
61                    sc.close();
62                }
63            }
64        } finally {
65            acceptSelector.close();
66        }
67    }
68
69    private static class Server extends TestThread {
70        final ServerSocketChannel ssc;
71        Server() throws IOException {
72            super("Server", System.err);
73            this.ssc = ServerSocketChannel.open()
74                .bind(new InetSocketAddress(0));
75        }
76        int port() {
77            return ssc.socket().getLocalPort();
78        }
79        void go() throws Exception {
80            try {
81                server(ssc);
82            } finally {
83                ssc.close();
84            }
85        }
86    }
87
88    static void client(int port) throws Exception {
89        // Get a connection from the server
90        InetAddress lh = InetAddress.getLocalHost();
91        InetSocketAddress isa
92            = new InetSocketAddress(lh, port);
93        int connectFailures = 0;
94        boolean result = false;
95        SocketChannel sc = SocketChannel.open();
96        for (;;) {
97            try {
98                result = sc.connect(isa);
99                break;
100            } catch (java.net.ConnectException e) {
101                connectFailures++;
102                if (connectFailures > 30)
103                    throw new RuntimeException("Cannot connect");
104                Thread.currentThread().sleep(100);
105                sc = SocketChannel.open();
106            }
107        }
108        if (result) {
109            System.err.println("Connected");
110        } else {
111            // Only happens when server and client are on separate machines
112            System.err.println("Connection pending...");
113            connectFailures = 0;
114            while (!result) {
115                try {
116                    result = sc.finishConnect();
117                    if (!result)
118                        System.err.println("Not finished");
119                    Thread.sleep(50);
120                } catch (java.net.ConnectException e) {
121                    Thread.sleep(100);
122                    connectFailures++;
123                    if (connectFailures > 30)
124                        throw new RuntimeException("Cannot finish connecting");
125                }
126            }
127            System.err.println("Finished connecting");
128        }
129
130        ByteBuffer bb = ByteBuffer.allocateDirect(1024);
131        if (sc.read(bb) < 0)
132            throw new RuntimeException("Failed to read from server");
133        if (bb.get(0) != 42)
134            throw new RuntimeException("Read wrong byte from server");
135        System.err.println("Read from server");
136        sc.close();
137    }
138
139    public static void main(String[] args) throws Exception {
140        Server server = new Server();
141        server.start();
142        try {
143            client(server.port());
144        } finally {
145            server.interrupt();
146            server.finish(2000);
147        }
148    }
149
150}
151