Path: blob/master/test/jdk/java/nio/channels/Selector/OutOfBand.java
41153 views
/*1* Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 621370225* @summary OOB data causes a SocketChannel, with OOBINLINE disabled, to be selected26*/2728/* @test29* @requires (os.family == "windows")30* @run main/othervm -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider OutOfBand31*/3233import java.net.*;34import java.nio.ByteBuffer;35import java.nio.channels.*;36import java.io.IOException;3738public class OutOfBand {3940public static void main(String[] args) throws Exception {41ServerSocketChannel ssc = null;42SocketChannel sc = null;43Selector sel = null;44Socket s = null;4546try {47// establish loopback connection.48ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));49s = new Socket(InetAddress.getLocalHost(),50ssc.socket().getLocalPort());51sc = ssc.accept();5253sel = Selector.open();54sc.configureBlocking(false);55sc.register(sel, SelectionKey.OP_READ);5657// OOB data should be disabled by default58if (sc.socket().getOOBInline())59throw new RuntimeException("SO_OOBINLINE enabled");60test(s, false, 0, 0, sel);61test(s, false, 512, 0, sel);62test(s, false, 0, 512, sel);63test(s, false, 512, 512, sel);6465// enable SO_OOBINLINE66sc.socket().setOOBInline(true);6768// OOB data should be received69test(s, true, 0, 0, sel);70test(s, true, 512, 0, sel);71test(s, true, 0, 512, sel);72test(s, true, 512, 512, sel);7374} finally {75if (sel != null) sel.close();76if (sc != null) sc.close();77if (ssc != null) ssc.close();78if (s != null) sc.close();79}80}8182static void test(Socket s, boolean urgentExpected,83int bytesBefore, int bytesAfter,84Selector sel)85throws IOException86{87// send data88int bytesExpected = 0;89if (bytesBefore > 0) {90s.getOutputStream().write(new byte[bytesBefore]);91bytesExpected += bytesBefore;92}93s.sendUrgentData(0xff);94if (urgentExpected)95bytesExpected++;96if (bytesAfter > 0) {97s.getOutputStream().write(new byte[bytesAfter]);98bytesExpected += bytesAfter;99}100101// receive data, checking for spurious wakeups and reads102int spuriousWakeups = 0;103int spuriousReads = 0;104int bytesRead = 0;105ByteBuffer bb = ByteBuffer.allocate(100);106for (;;) {107int n = sel.select(2000);108if (n == 0) {109if (bytesRead == bytesExpected) {110System.out.format("Selector wakeups %d\tSpurious reads %d%n",111spuriousWakeups, spuriousReads);112return;113}114if (++spuriousWakeups >= 3)115throw new RuntimeException("Selector appears to be spinning" +116" or data not received");117continue;118}119if (n > 1)120throw new RuntimeException("More than one key selected????");121SelectionKey key = sel.selectedKeys().iterator().next();122bb.clear();123n = ((SocketChannel)key.channel()).read(bb);124if (n == 0) {125if (++spuriousReads >=3)126throw new RuntimeException("Too many spurious reads");127} else {128bytesRead += n;129if (bytesRead > bytesExpected)130throw new RuntimeException("Received more than expected");131}132sel.selectedKeys().clear();133}134}135}136137138