| /* | |
| * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. | |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| * | |
| * This code is free software; you can redistribute it and/or modify it | |
| * under the terms of the GNU General Public License version 2 only, as | |
| * published by the Free Software Foundation. | |
| * | |
| * This code is distributed in the hope that it will be useful, but WITHOUT | |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| * version 2 for more details (a copy is included in the LICENSE file that | |
| * accompanied this code). | |
| * | |
| * You should have received a copy of the GNU General Public License version | |
| * 2 along with this work; if not, write to the Free Software Foundation, | |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| * | |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| * or visit www.oracle.com if you need additional information or have any | |
| * questions. | |
| */ | |
| import jdk.test.lib.NetworkConfiguration; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import java.io.OutputStream; | |
| import java.net.DatagramPacket; | |
| import java.net.DatagramSocket; | |
| import java.net.Inet4Address; | |
| import java.net.Inet6Address; | |
| import java.net.InetAddress; | |
| import java.net.InetSocketAddress; | |
| import java.net.Socket; | |
| import java.net.SocketAddress; | |
| public class Tests { | |
| static final boolean isWindows = | |
| System.getProperty("os.name").startsWith("Windows"); | |
| static final boolean isMacOS = | |
| System.getProperty("os.name").contains("OS X"); | |
| /** | |
| * performs a simple exchange of data between the two sockets | |
| * and throws an exception if there is any problem. | |
| */ | |
| public static void simpleDataExchange (Socket s1, Socket s2) | |
| throws Exception { | |
| InputStream i1 = s1.getInputStream(); | |
| InputStream i2 = s2.getInputStream(); | |
| OutputStream o1 = s1.getOutputStream(); | |
| OutputStream o2 = s2.getOutputStream(); | |
| startSimpleWriter("SimpleWriter-1", o1, 100); | |
| startSimpleWriter("SimpleWriter-2", o2, 200); | |
| simpleRead (i2, 100); | |
| simpleRead (i1, 200); | |
| } | |
| static void startSimpleWriter(String threadName, final OutputStream os, final int start) { | |
| (new Thread(new Runnable() { | |
| public void run() { | |
| try { simpleWrite(os, start); } | |
| catch (Exception e) {unexpected(e); } | |
| }}, threadName)).start(); | |
| } | |
| static void unexpected(Exception e ) { | |
| System.out.println("Unexcepted Exception: " + e); | |
| e.printStackTrace(); | |
| } | |
| /** | |
| * Send a packet from s1 to s2 (ia2/s2.localPort) and check it | |
| * Send a packet from s2 to s1 (ia1/s1.localPort) and check it | |
| */ | |
| public static void simpleDataExchange (DatagramSocket s1, InetAddress ia1, | |
| DatagramSocket s2, InetAddress ia2) | |
| throws Exception { | |
| SocketAddress dest1 = new InetSocketAddress (ia1, s1.getLocalPort()); | |
| dprintln ("dest1 = " + dest1); | |
| SocketAddress dest2 = new InetSocketAddress (ia2, s2.getLocalPort()); | |
| dprintln ("dest2 = " + dest2); | |
| byte[] ba = "Hello world".getBytes(); | |
| byte[] bb = "HELLO WORLD1".getBytes(); | |
| DatagramPacket p1 = new DatagramPacket (ba, ba.length, dest1); | |
| DatagramPacket p2 = new DatagramPacket (ba, ba.length, dest2); | |
| DatagramPacket r1 = new DatagramPacket (new byte[256], 256); | |
| DatagramPacket r2 = new DatagramPacket (new byte[256], 256); | |
| s2.send (p1); | |
| s1.send (p2); | |
| s1.receive (r1); | |
| s2.receive (r2); | |
| comparePackets (p1, r1); | |
| comparePackets (p2, r2); | |
| } | |
| /** | |
| * Send a packet from s1 to s2 (ia2/s2.localPort) and send same packet | |
| * back from s2 to sender. Check s1 receives original packet | |
| */ | |
| public static void datagramEcho (DatagramSocket s1, DatagramSocket s2, | |
| InetAddress ia2) | |
| throws Exception { | |
| byte[] ba = "Hello world".getBytes(); | |
| DatagramPacket p1; | |
| SocketAddress dest2 = null; | |
| if (ia2 != null) { | |
| dest2 = new InetSocketAddress (ia2, s2.getLocalPort()); | |
| p1 = new DatagramPacket (ba, ba.length, dest2); | |
| } else { | |
| p1 = new DatagramPacket (ba, ba.length); | |
| } | |
| dprintln ("dest2 = " + dest2); | |
| dprintln ("sender endpoint = " + s1.getLocalSocketAddress()); | |
| dprintln ("echo endpoint = " + s2.getLocalSocketAddress()); | |
| DatagramPacket r1 = new DatagramPacket (new byte[256], 256); | |
| DatagramPacket r2 = new DatagramPacket (new byte[256], 256); | |
| s1.send (p1); | |
| s2.receive (r1); | |
| s2.send (r1); | |
| s1.receive (r2); | |
| comparePackets (p1, r1); | |
| comparePackets (p1, r2); | |
| } | |
| public static void comparePackets (DatagramPacket p1, DatagramPacket p2) | |
| throws Exception { | |
| byte[] b1 = p1.getData(); | |
| byte[] b2 = p2.getData(); | |
| int len = p1.getLength () > p2.getLength() ? p2.getLength() | |
| : p1.getLength(); | |
| for (int i=0; i<len; i++) { | |
| if (b1[i] != b2[i]) { | |
| throw new Exception ("packets not the same"); | |
| } | |
| } | |
| } | |
| /* check the timeout breached lower bound time rule */ | |
| public static void checkIfTimeOut(long got, long expected) { | |
| dprintln("checkIfTimeOut: got = " + got + " lower bound = " + expected); | |
| if (got < expected) { | |
| throw new RuntimeException("checkIfTimeOut failed: got " + got | |
| + ", expected at least " + expected ); | |
| } | |
| } | |
| static boolean debug = false; | |
| public static void checkDebug (String[] args) { | |
| debug = args.length > 0 && args[0].equals("-d"); | |
| } | |
| public static void dprint (String s) { | |
| if (debug) { | |
| System.out.print (s); | |
| } | |
| } | |
| public static void dprintln (String s) { | |
| if (debug) { | |
| System.out.println (s); | |
| } | |
| } | |
| public static Inet4Address getFirstLocalIPv4Address () { | |
| return getNetworkConfig().ip4Addresses() | |
| .filter(a -> !a.isLoopbackAddress()) | |
| .findFirst() | |
| .orElse(null); | |
| } | |
| public static Inet6Address getFirstLocalIPv6Address () { | |
| return getNetworkConfig().ip6Addresses() | |
| .filter(a -> !a.isLoopbackAddress()) | |
| .findFirst() | |
| .orElse(null); | |
| } | |
| private static NetworkConfiguration getNetworkConfig() { | |
| try { | |
| return NetworkConfiguration.probe(); | |
| } catch (IOException e) { | |
| System.out.println("Failed to probe NetworkConfiguration"); | |
| throw new RuntimeException(e); | |
| } | |
| } | |
| /** | |
| * Throws a RuntimeException if the boolean condition is false | |
| */ | |
| public static void t_assert (boolean assertion) { | |
| if (assertion) { | |
| return; | |
| } | |
| Throwable t = new Throwable(); | |
| StackTraceElement[] strace = t.getStackTrace(); | |
| String msg = "Assertion failed at: " + strace[1].toString(); | |
| throw new RuntimeException (msg); | |
| } | |
| private static void simpleRead (InputStream is, int start) throws Exception { | |
| byte b[] = new byte [2]; | |
| for (int i=start; i<start+100; i++) { | |
| int x = is.read (b); | |
| if (x == 1) { | |
| x += is.read (b,1,1); | |
| } | |
| if (x!=2) { | |
| throw new Exception ("read error"); | |
| } | |
| int r = bytes (b[0], b[1]); | |
| if (r != i) { | |
| throw new Exception ("read " + r + " expected " +i); | |
| } | |
| } | |
| } | |
| /* convert signed bytes to unisigned int */ | |
| private static int bytes (byte b1, byte b2) { | |
| int i1 = (int)b1 & 0xFF; | |
| int i2 = (int)b2 & 0xFF; | |
| return i1 * 256 + i2; | |
| } | |
| static void simpleWrite (OutputStream os, int start) throws Exception { | |
| byte b[] = new byte [2]; | |
| for (int i=start; i<start+100; i++) { | |
| b[0] = (byte) (i / 256); | |
| b[1] = (byte) (i % 256); | |
| os.write (b); | |
| } | |
| } | |
| private static class Runner extends Thread { | |
| Runnable runnee; | |
| long delay; | |
| Runner (Runnable runnee, long delay) { | |
| super(); | |
| this.runnee = runnee; | |
| this.delay = delay; | |
| } | |
| public void run () { | |
| try { | |
| Thread.sleep (delay); | |
| runnee.run (); | |
| } catch (Exception e) { | |
| e.printStackTrace(); | |
| } | |
| } | |
| } | |
| /* | |
| * Take the given Runnable and run it in a spawned thread | |
| * after the given time has elapsed. runAfter() returns immediately | |
| */ | |
| public static void runAfter (long millis, Runnable runnee) { | |
| Runner runner = new Runner (runnee, millis); | |
| runner.start (); | |
| } | |
| static String osname; | |
| static { | |
| osname = System.getProperty ("os.name"); | |
| } | |
| static boolean isLinux () { | |
| return osname.equals ("Linux"); | |
| } | |
| static boolean isWindows () { | |
| return osname.startsWith ("Windows"); | |
| } | |
| } |