jdk/test/java/nio/channels/SocketChannel/OutOfBand.java
changeset 6117 471ae95609d5
child 29224 8433f5f46142
equal deleted inserted replaced
6116:3880a05ff32e 6117:471ae95609d5
       
     1 /*
       
     2  * Copyright (c) 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 socket adapter sendUrgentData method
       
    26  * @bug 6963907
       
    27  */
       
    28 
       
    29 import java.net.*;
       
    30 import java.nio.ByteBuffer;
       
    31 import java.nio.channels.*;
       
    32 import java.io.IOException;
       
    33 import java.util.Random;
       
    34 
       
    35 public class OutOfBand {
       
    36 
       
    37     private static final Random rand = new Random();
       
    38 
       
    39     public static void main(String[] args) throws Exception {
       
    40         ServerSocketChannel ssc = null;
       
    41         SocketChannel sc1 = null;
       
    42         SocketChannel sc2 = null;
       
    43 
       
    44         try {
       
    45 
       
    46             // establish loopback connection
       
    47             ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
       
    48             InetAddress lh = InetAddress.getLocalHost();
       
    49             SocketAddress remote =
       
    50                 new InetSocketAddress(lh, ssc.socket().getLocalPort());
       
    51             sc1 = SocketChannel.open(remote);
       
    52             sc2 = ssc.accept();
       
    53 
       
    54             // enable SO_OOBLINE on server side
       
    55             sc2.socket().setOOBInline(true);
       
    56 
       
    57             // run tests
       
    58             test1(sc1, sc2);
       
    59             test2(sc1, sc2);
       
    60             test3(sc1, sc2);
       
    61             test4(sc1);
       
    62 
       
    63         } finally {
       
    64             if (sc1 != null) sc1.close();
       
    65             if (sc2 != null) sc2.close();
       
    66             if (ssc != null) ssc.close();
       
    67         }
       
    68     }
       
    69 
       
    70     /**
       
    71      * Basic test to check that OOB/TCP urgent byte is received.
       
    72      */
       
    73     static void test1(SocketChannel client, SocketChannel server)
       
    74         throws Exception
       
    75     {
       
    76         assert server.socket().getOOBInline();
       
    77         ByteBuffer bb = ByteBuffer.allocate(100);
       
    78         for (int i=0; i<1000; i++) {
       
    79             int b1 = -127 + rand.nextInt(384);
       
    80             client.socket().sendUrgentData(b1);
       
    81 
       
    82             bb.clear();
       
    83             if (server.read(bb) != 1)
       
    84                 throw new RuntimeException("One byte expected");
       
    85             bb.flip();
       
    86             byte b2 = bb.get();
       
    87             if ((byte)b1 != b2)
       
    88                 throw new RuntimeException("Unexpected byte");
       
    89         }
       
    90     }
       
    91 
       
    92     /**
       
    93      * Basic test to check that OOB/TCP urgent byte is received, maybe with
       
    94      * OOB mark changing.
       
    95      */
       
    96     static void test2(final SocketChannel client, SocketChannel server)
       
    97         throws Exception
       
    98     {
       
    99         assert server.socket().getOOBInline();
       
   100         Runnable sender = new Runnable() {
       
   101             public void run() {
       
   102                 try {
       
   103                     for (int i=0; i<256; i++)
       
   104                         client.socket().sendUrgentData(i);
       
   105                 } catch (IOException ioe) {
       
   106                     ioe.printStackTrace();
       
   107                 }
       
   108             }
       
   109         };
       
   110         Thread thr = new Thread(sender);
       
   111         thr.start();
       
   112 
       
   113         ByteBuffer bb = ByteBuffer.allocate(256);
       
   114         while (bb.hasRemaining()) {
       
   115             if (server.read(bb) < 0)
       
   116                 throw new RuntimeException("Unexpected EOF");
       
   117         }
       
   118         bb.flip();
       
   119         byte expect = 0;
       
   120         while (bb.hasRemaining()) {
       
   121             if (bb.get() != expect)
       
   122                 throw new RuntimeException("Unexpected byte");
       
   123             expect++;
       
   124         }
       
   125 
       
   126         thr.join();
       
   127     }
       
   128 
       
   129     /**
       
   130      * Test that is close to some real world examples where an urgent byte is
       
   131      * used to "cancel" a long running query or transaction on the server.
       
   132      */
       
   133     static void test3(SocketChannel client, final SocketChannel server)
       
   134         throws Exception
       
   135     {
       
   136         final int STOP = rand.nextInt(256);
       
   137 
       
   138         assert server.socket().getOOBInline();
       
   139         Runnable reader = new Runnable() {
       
   140             public void run() {
       
   141                 ByteBuffer bb = ByteBuffer.allocate(100);
       
   142                 try {
       
   143                     int n = server.read(bb);
       
   144                     if (n != 1) {
       
   145                         String msg = (n < 0) ? "Unexpected EOF" :
       
   146                                                "One byte expected";
       
   147                         throw new RuntimeException(msg);
       
   148                     }
       
   149                     bb.flip();
       
   150                     if (bb.get() != (byte)STOP)
       
   151                         throw new RuntimeException("Unexpected byte");
       
   152                     bb.flip();
       
   153                     server.write(bb);
       
   154                 } catch (IOException ioe) {
       
   155                     ioe.printStackTrace();
       
   156                 }
       
   157 
       
   158             }
       
   159         };
       
   160 
       
   161         Thread thr = new Thread(reader);
       
   162         thr.start();
       
   163 
       
   164         // "stop" server
       
   165         client.socket().sendUrgentData(STOP);
       
   166 
       
   167         // wait for server reply
       
   168         ByteBuffer bb = ByteBuffer.allocate(100);
       
   169         int n = client.read(bb);
       
   170         if (n != 1)
       
   171             throw new RuntimeException("Unexpected number of bytes");
       
   172         bb.flip();
       
   173         if (bb.get() != (byte)STOP)
       
   174             throw new RuntimeException("Unexpected reply");
       
   175 
       
   176         thr.join();
       
   177     }
       
   178 
       
   179     static void test4(SocketChannel sc) throws IOException {
       
   180         boolean blocking = sc.isBlocking();
       
   181         sc.configureBlocking(false);
       
   182         try {
       
   183             sc.socket().sendUrgentData(0);
       
   184             throw new RuntimeException("IllegalBlockingModeException expected");
       
   185         } catch (IllegalBlockingModeException x) {
       
   186             // expected
       
   187         } finally {
       
   188             sc.configureBlocking(blocking);
       
   189         }
       
   190     }
       
   191 }