Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8310807: java/nio/channels/DatagramChannel/Connect.java timed out
Reviewed-by: msheppar, jpai
  • Loading branch information
dfuch committed Nov 21, 2023
1 parent 21a59b9 commit 570dffb
Showing 1 changed file with 79 additions and 36 deletions.
115 changes: 79 additions & 36 deletions 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
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

3 comments on commit 570dffb

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

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

@SoniaZaldana
Copy link
Member

Choose a reason for hiding this comment

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

/backport jdk17u-dev

@openjdk
Copy link

@openjdk openjdk bot commented on 570dffb Dec 19, 2023

Choose a reason for hiding this comment

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

@SoniaZaldana the backport was successfully created on the branch backport-SoniaZaldana-570dffb1 in my personal fork of openjdk/jdk17u-dev. To create a pull request with this backport targeting openjdk/jdk17u-dev:master, just click the following link:

➡️ Create pull request

The title of the pull request is automatically filled in correctly and below you find a suggestion for the pull request body:

Hi all,

This pull request contains a backport of commit 570dffb1 from the openjdk/jdk repository.

The commit being backported was authored by Daniel Fuchs on 21 Nov 2023 and was reviewed by Mark Sheppard and Jaikiran Pai.

Thanks!

If you need to update the source branch of the pull then run the following commands in a local clone of your personal fork of openjdk/jdk17u-dev:

$ git fetch https://github.com/openjdk-bots/jdk17u-dev.git backport-SoniaZaldana-570dffb1:backport-SoniaZaldana-570dffb1
$ git checkout backport-SoniaZaldana-570dffb1
# make changes
$ git add paths/to/changed/files
$ git commit --message 'Describe additional changes made'
$ git push https://github.com/openjdk-bots/jdk17u-dev.git backport-SoniaZaldana-570dffb1

Please sign in to comment.