Skip to content

Commit

Permalink
8310807: java/nio/channels/DatagramChannel/Connect.java timed out
Browse files Browse the repository at this point in the history
Backport-of: 570dffb104fc37f053fcdf38a24aa2cabdc921c0
  • Loading branch information
shipilev committed Dec 19, 2023
1 parent 0c92460 commit 5d32860
Showing 1 changed file with 79 additions and 36 deletions.
115 changes: 79 additions & 36 deletions test/jdk/java/nio/channels/DatagramChannel/Connect.java
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -23,25 +23,36 @@

/* @test
* @bug 4313882 7183800
* @run main/othervm Connect
* @summary Test DatagramChannel's send and receive methods
*/

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();
}

Expand Down Expand Up @@ -99,41 +110,62 @@ public static class Initiator implements AutoCloseable, Runnable {

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");
}
}

Expand All @@ -156,26 +188,37 @@ SocketAddress getSocketAddress() throws IOException {
}

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);

// Reply to sender
dc.connect(sa);
bb.flip();
log.println("Responder attempting to write: " + dc.getRemoteAddress().toString());
dc.write(bb);
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.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");
}
}

Expand Down

1 comment on commit 5d32860

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.