diff --git a/test/jdk/java/nio/channels/DatagramChannel/Connect.java b/test/jdk/java/nio/channels/DatagramChannel/Connect.java index 5b2bbea4e5b..082a3234cc5 100644 --- a/test/jdk/java/nio/channels/DatagramChannel/Connect.java +++ b/test/jdk/java/nio/channels/DatagramChannel/Connect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, 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 @@ -23,6 +23,7 @@ /* @test * @bug 4313882 7183800 + * @run main/othervm Connect * @summary Test DatagramChannel's send and receive methods */ @@ -30,18 +31,28 @@ import java.io.*; import java.net.*; import java.nio.*; import java.nio.channels.*; -import java.nio.charset.*; +import java.time.Instant; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.stream.Stream; +import static java.nio.charset.StandardCharsets.US_ASCII; + public class Connect { - static PrintStream log = System.err; + static final PrintStream err = System.err; + static final String TIME_STAMP = Instant.now().toString(); + static final String MESSAGE = "Hello " + TIME_STAMP; + static final String OTHER = "Hey " + TIME_STAMP; + static final String RESPONSE = "Hi " + TIME_STAMP; + static final int MAX = Math.max(256, MESSAGE.getBytes(US_ASCII).length + 16); public static void main(String[] args) throws Exception { + assert MAX > MESSAGE.getBytes(US_ASCII).length; + assert MAX > OTHER.getBytes(US_ASCII).length; + assert MAX > RESPONSE.getBytes(US_ASCII).length; test(); } @@ -99,41 +110,62 @@ public class Connect { public void run() { try { - ByteBuffer bb = ByteBuffer.allocateDirect(256); - bb.put("hello".getBytes()); + byte[] bytes = MESSAGE.getBytes(US_ASCII); + ByteBuffer bb = ByteBuffer.allocateDirect(MAX); + bb.put(bytes); bb.flip(); - log.println("Initiator connecting to " + connectSocketAddress); + err.println("Initiator connecting to: " + connectSocketAddress); dc.connect(connectSocketAddress); + err.println("Initiator bound to: " + dc.getLocalAddress()); // Send a message - log.println("Initiator attempting to write to Responder at " + connectSocketAddress.toString()); + err.println("Initiator attempting to write to Responder at " + connectSocketAddress); dc.write(bb); // Try to send to some other address try { int port = dc.socket().getLocalPort(); InetAddress loopback = InetAddress.getLoopbackAddress(); - InetSocketAddress otherAddress = new InetSocketAddress(loopback, (port == 3333 ? 3332 : 3333)); - log.println("Testing if Initiator throws AlreadyConnectedException" + otherAddress.toString()); - dc.send(bb, otherAddress); + try (DatagramChannel other = DatagramChannel.open()) { + InetSocketAddress otherAddress = new InetSocketAddress(loopback, 0); + other.bind(otherAddress); + err.println("Testing if Initiator throws AlreadyConnectedException"); + otherAddress = (InetSocketAddress) other.getLocalAddress(); + assert port != otherAddress.getPort(); + assert !connectSocketAddress.equals(otherAddress); + err.printf("Initiator sending \"%s\" to other address %s%n", OTHER, otherAddress); + dc.send(ByteBuffer.wrap(OTHER.getBytes(US_ASCII)), otherAddress); + } throw new RuntimeException("Initiator allowed send to other address while already connected"); } catch (AlreadyConnectedException ace) { // Correct behavior + err.println("Initiator got expected " + ace); } - // Read a reply - bb.flip(); - log.println("Initiator waiting to read"); - dc.read(bb); - bb.flip(); - CharBuffer cb = StandardCharsets.US_ASCII. - newDecoder().decode(bb); - log.println("Initiator received from Responder at " + connectSocketAddress + ": " + cb); + // wait for response + while (true) { + // zero out buffer + bb.clear(); + bb.put(new byte[bb.remaining()]); + bb.flip(); + + // Read a reply + err.println("Initiator waiting to read"); + dc.read(bb); + bb.flip(); + CharBuffer cb = US_ASCII.newDecoder().decode(bb); + err.println("Initiator received from Responder at " + connectSocketAddress + ": " + cb); + if (!RESPONSE.equals(cb.toString())) { + err.println("Initiator received unexpected message: continue waiting"); + continue; + } + break; + } } catch (Exception ex) { - log.println("Initiator threw exception: " + ex); + err.println("Initiator threw exception: " + ex); throw new RuntimeException(ex); } finally { - log.println("Initiator finished"); + err.println("Initiator finished"); } } @@ -156,26 +188,37 @@ public class Connect { } public void run() { + ByteBuffer bb = ByteBuffer.allocateDirect(MAX); try { - // Listen for a message - ByteBuffer bb = ByteBuffer.allocateDirect(100); - log.println("Responder waiting to receive"); - SocketAddress sa = dc.receive(bb); - bb.flip(); - CharBuffer cb = StandardCharsets.US_ASCII. - newDecoder().decode(bb); - log.println("Responder received from Initiator at" + sa + ": " + cb); + while (true) { + // Listen for a message + err.println("Responder waiting to receive"); + SocketAddress sa = dc.receive(bb); + bb.flip(); + CharBuffer cb = US_ASCII. + newDecoder().decode(bb); + err.println("Responder received from Initiator at " + sa + ": " + cb); + if (!MESSAGE.equals(cb.toString())) { + err.println("Responder received unexpected message: continue waiting"); + bb.clear(); + continue; + } - // Reply to sender - dc.connect(sa); - bb.flip(); - log.println("Responder attempting to write: " + dc.getRemoteAddress().toString()); - dc.write(bb); + // Reply to sender + dc.connect(sa); + bb.clear(); + bb.put(RESPONSE.getBytes(US_ASCII)); + bb.flip(); + err.println("Responder attempting to write: " + dc.getRemoteAddress()); + dc.write(bb); + bb.flip(); + break; + } } catch (Exception ex) { - log.println("Responder threw exception: " + ex); + err.println("Responder threw exception: " + ex); throw new RuntimeException(ex); } finally { - log.println("Responder finished"); + err.println("Responder finished"); } }