1 /*
   2  * Copyright (c) 2000, 2018, 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 8195160
  26  * @summary Unit test for server-socket channels
  27  * @requires (os.family == "linux")
  28  * @library .. /test/lib
  29  * @build RsocketTest
  30  * @run main/othervm -Djava.net.preferIPv4Stack=true Basic
  31  */
  32 
  33 import java.io.*;
  34 import java.net.*;
  35 import java.nio.*;
  36 import java.nio.channels.*;
  37 import java.util.Random;
  38 import jdk.net.Sockets;
  39 
  40 public class Basic {
  41 
  42     static PrintStream log = System.err;
  43 
  44     static class Server
  45         extends TestThread
  46     {
  47         ServerSocketChannel ssc;
  48         boolean block;
  49 
  50         Server(ServerSocketChannel ssc, boolean block) {
  51             super("Server", Basic.log);
  52             this.ssc = ssc;
  53             this.block = block;
  54         }
  55 
  56         void go() throws Exception {
  57             log.println("Server: Listening "
  58                         + (block ? "(blocking)" : "(non-blocking)"));
  59             if (!block)
  60                 ssc.configureBlocking(false);
  61             log.println("  " + ssc);
  62             //log.println("  " + ssc.options());
  63             SocketChannel sc = null;
  64             for (;;) {
  65                 sc = ssc.accept();
  66                 if (sc != null) {
  67                     break;
  68                 }
  69                 log.println("Server: Sleeping...");
  70                 Thread.sleep(50);
  71             }
  72             log.println("Server: Accepted " + sc);
  73             ByteBuffer bb = ByteBuffer.allocateDirect(100);
  74             if (sc.read(bb) != 1)
  75                 throw new Exception("Read failed");
  76             bb.flip();
  77             byte b = bb.get();
  78             log.println("Server: Read " + b + ", writing " + (b + 1));
  79             bb.clear();
  80             bb.put((byte)43);
  81             bb.flip();
  82             if (sc.write(bb) != 1)
  83                 throw new Exception("Write failed");
  84             sc.close();
  85             ssc.close();
  86             log.println("Server: Finished");
  87         }
  88 
  89     }
  90 
  91     static class Client
  92         extends TestThread
  93     {
  94         int port;
  95         boolean dally;
  96 
  97         Client(int port, boolean block) {
  98             super("Client", Basic.log);
  99             this.port = port;
 100             this.dally = !block;
 101         }
 102 
 103         public void go() throws Exception {
 104             if (dally)
 105                 Thread.sleep(200);
 106             InetSocketAddress isa
 107                 = new InetSocketAddress(InetAddress.getLocalHost(), port);
 108             log.println("Client: Connecting to " + isa);
 109             SocketChannel sc = Sockets.openRdmaSocketChannel();
 110             sc.connect(isa);
 111             log.println("Client: Connected");
 112             ByteBuffer bb = ByteBuffer.allocateDirect(512);
 113             bb.put((byte)42).flip();
 114             log.println("Client: Writing " + bb.get(0));
 115             if (sc.write(bb) != 1)
 116                 throw new Exception("Write failed");
 117             bb.clear();
 118             if (sc.read(bb) != 1)
 119                 throw new Exception("Read failed");
 120             bb.flip();
 121             if (bb.get() != 43)
 122                 throw new Exception("Read " + bb.get(bb.position() - 1));
 123             log.println("Client: Read " + bb.get(0));
 124             sc.close();
 125             log.println("Client: Finished");
 126         }
 127 
 128     }
 129 
 130     static void test(boolean block) throws Exception {
 131         ServerSocketChannel ssc = Sockets.openRdmaServerSocketChannel();
 132         ssc.socket().setReuseAddress(true);
 133         InetAddress lh = InetAddress.getLocalHost();
 134         int port;
 135         Random r = new Random();
 136         for (;;) {
 137             port = r.nextInt((1 << 16) - 1024) + 1024;
 138             InetSocketAddress isa = new InetSocketAddress(lh, port);
 139             try {
 140                 ssc.socket().bind(isa);
 141             } catch (IOException x) {
 142                 continue;
 143             }
 144             break;
 145         }
 146 
 147         Server server = new Server(ssc, block);
 148         Client client = new Client(port, block);
 149         server.start();
 150         client.start();
 151         if ((server.finish(0) & client.finish(0)) == 0)
 152             throw new Exception("Failure");
 153         log.println();
 154     }
 155 
 156     public static void main(String[] args) throws Exception {
 157         if (!RsocketTest.isRsocketAvailable())
 158             return;
 159 
 160         log.println();
 161         test(true);
 162         test(false);
 163     }
 164 
 165 }