1 /* 2 * Copyright (c) 2002, 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 * @bug 4617165 26 * @summary Ensure that socket hangups are handled correctly 27 * @library .. 28 * @build TestUtil 29 * @run main Hangup 30 */ 31 32 import java.io.*; 33 import java.net.*; 34 import java.nio.*; 35 import java.nio.channels.*; 36 import java.util.*; 37 38 39 public class Hangup { 40 41 static PrintStream log = System.err; 42 static int failures = 0; 43 44 private static class Failure 45 extends RuntimeException 46 { 47 Failure(String s)48 Failure(String s) { 49 super(s); 50 } 51 52 } 53 doSelect(Selector sel, SelectionKey sk, int count)54 static void doSelect(Selector sel, SelectionKey sk, int count) 55 throws IOException 56 { 57 int n = sel.select(); 58 if (n != 1) 59 throw new Failure("Select returned zero"); 60 Set sks = sel.selectedKeys(); 61 if (sks.size() != 1) 62 throw new Failure("Wrong size for selected-key set: " 63 + sks.size()); 64 if (!sks.remove(sk)) 65 throw new Failure("Key not in selected-key set"); 66 log.println("S: Socket selected #" + count); 67 } 68 dally()69 static void dally() { 70 try { 71 Thread.sleep(100); 72 } catch (InterruptedException x) { } 73 } 74 test(boolean writeFromClient, boolean readAfterClose)75 static void test(boolean writeFromClient, boolean readAfterClose) 76 throws IOException 77 { 78 79 ServerSocketChannel ssc = null; 80 SocketChannel cl = null; // client end 81 SocketChannel sv = null; // server end 82 Selector sel = null; 83 84 log.println(); 85 log.println("Test: writeFromClient = " + writeFromClient 86 + ", readAfterClose = " + readAfterClose); 87 88 try { 89 90 int ns = 0; // Number of selection operations done 91 92 // Set up server socket 93 ssc = ServerSocketChannel.open(); 94 SocketAddress sa = TestUtil.bindToRandomPort(ssc); 95 log.println("S: Listening on port " 96 + ssc.socket().getLocalPort()); 97 98 // Connect client 99 cl = SocketChannel.open(sa); 100 log.println("C: Connected via port " 101 + cl.socket().getLocalPort()); 102 103 // Accept client connection 104 sv = ssc.accept(); 105 log.println("S: Client connection accepted"); 106 107 // Create selector and register server side 108 sel = Selector.open(); 109 sv.configureBlocking(false); 110 SelectionKey sk = sv.register(sel, SelectionKey.OP_READ); 111 112 ByteBuffer stuff = ByteBuffer.allocate(10); 113 int n; 114 115 if (writeFromClient) { 116 117 // Write from client, read from server 118 119 stuff.clear(); 120 if (cl.write(stuff) != stuff.capacity()) 121 throw new Failure("Incorrect number of bytes written"); 122 log.println("C: Wrote stuff"); 123 dally(); 124 125 doSelect(sel, sk, ++ns); 126 127 stuff.clear(); 128 if (sv.read(stuff) != stuff.capacity()) 129 throw new Failure("Wrong number of bytes read"); 130 log.println("S: Read stuff"); 131 } 132 133 // Close client side 134 cl.close(); 135 log.println("C: Socket closed"); 136 dally(); 137 138 // Select again 139 doSelect(sel, sk, ++ns); 140 141 if (readAfterClose) { 142 // Read from client after client has disconnected 143 stuff.clear(); 144 if (sv.read(stuff) != -1) 145 throw new Failure("Wrong number of bytes read"); 146 log.println("S: Read EOF"); 147 } 148 149 // Select a couple more times just to make sure we're doing 150 // the right thing 151 152 doSelect(sel, sk, ++ns); 153 doSelect(sel, sk, ++ns); 154 155 } finally { 156 if (ssc != null) 157 ssc.close(); 158 if (cl != null) 159 cl.close(); 160 if (sv != null) 161 sv.close(); 162 if (sel != null) 163 sel.close(); 164 } 165 166 } 167 main(String[] args)168 public static void main(String[] args) throws IOException { 169 170 for (boolean writeFromClient = false;; writeFromClient = true) { 171 for (boolean readAfterClose = false;; readAfterClose = true) { 172 try { 173 test(writeFromClient, readAfterClose); 174 } catch (Failure x) { 175 x.printStackTrace(log); 176 failures++; 177 } 178 if (readAfterClose) 179 break; 180 } 181 if (writeFromClient) 182 break; 183 } 184 185 if (failures > 0) { 186 log.println(); 187 throw new RuntimeException("Some tests failed"); 188 } 189 190 } 191 192 } 193