8380534: Use loopback address in java/net/DatagramPacket/ReuseBuf.java test

Reviewed-by: dfuchs
This commit is contained in:
Jaikiran Pai 2026-03-20 15:58:45 +00:00
parent f7c427feda
commit 396cc0ab6a

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2026, 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
@ -21,71 +21,132 @@
* questions.
*/
/**
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.util.concurrent.atomic.AtomicReference;
/*
* @test
*
* @bug 4424096
*
* @summary DatagramPacket spec needs clarification (reuse buf)
* @summary Verify the specification of DatagramPacket.getData()
*/
import java.net.*;
public class ReuseBuf {
static String msgs[] = {"Hello World", "Java", "Good Bye"};
static int port;
private static final String[] msgs = {"Hello World", "Java", "Good Bye"};
static class ServerThread extends Thread{
DatagramSocket ds;
public ServerThread() {
static class Server implements Runnable, AutoCloseable {
private final DatagramSocket ds;
private volatile boolean closed;
private final AtomicReference<Exception> serverFailure = new AtomicReference<>();
public Server(final InetSocketAddress bindAddr) {
try {
InetAddress local = InetAddress.getLocalHost();
InetSocketAddress bindaddr = new InetSocketAddress(local, 0);
ds = new DatagramSocket(bindaddr);
port = ds.getLocalPort();
this.ds = new DatagramSocket(bindAddr);
} catch (SocketException e) {
throw new RuntimeException(e);
}
System.out.println("Server bound to address: " + this.ds.getLocalSocketAddress());
}
private InetSocketAddress getServerAddress() {
return (InetSocketAddress) this.ds.getLocalSocketAddress();
}
private static void serverLog(final String msg) {
System.out.println("[server] " + msg);
}
@Override
public void run() {
serverLog("server processing started");
try {
doRun();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
// no need to be concerned with the exception
// if the server is already closed
if (!closed) {
this.serverFailure.set(e);
System.err.println("server exception: " + e);
e.printStackTrace();
}
} finally {
close();
}
}
public void run() {
byte b[] = new byte[100];
DatagramPacket dp = new DatagramPacket(b,b.length);
while (true) {
try {
ds.receive(dp);
String reply = new String(dp.getData(), dp.getOffset(), dp.getLength());
ds.send(new DatagramPacket(reply.getBytes(),reply.length(),
dp.getAddress(),dp.getPort()));
if (reply.equals(msgs[msgs.length-1])) {
break;
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
private void doRun() throws Exception {
byte[] b = new byte[100];
DatagramPacket dp = new DatagramPacket(b, b.length);
while (!closed) {
serverLog("waiting to receive a message at " + ds.getLocalSocketAddress());
ds.receive(dp);
String reply = new String(dp.getData(), dp.getOffset(), dp.getLength());
serverLog("replying to " + dp.getAddress() + ":" + dp.getPort());
ds.send(new DatagramPacket(reply.getBytes(), reply.length(),
dp.getAddress(), dp.getPort()));
if (reply.equals(msgs[msgs.length - 1])) {
break;
}
}
ds.close();
}
@Override
public void close() {
if (this.closed) {
return;
}
synchronized (this) {
if (this.closed) {
return;
}
this.closed = true;
}
System.out.println("Server closing " + ds.getLocalSocketAddress());
this.ds.close();
}
}
public static void main(String args[]) throws Exception {
ServerThread st = new ServerThread();
st.start();
InetAddress local = InetAddress.getLocalHost();
InetSocketAddress bindaddr = new InetSocketAddress(local, 0);
DatagramSocket ds = new DatagramSocket(bindaddr);
byte b[] = new byte[100];
DatagramPacket dp = new DatagramPacket(b,b.length);
for (int i = 0; i < msgs.length; i++) {
ds.send(new DatagramPacket(msgs[i].getBytes(),msgs[i].length(),
InetAddress.getLocalHost(),
port));
ds.receive(dp);
if (!msgs[i].equals(new String(dp.getData(), dp.getOffset(), dp.getLength()))) {
throw new RuntimeException("Msg expected: "+msgs[i] +msgs[i].length()+
"msg received: "+new String(dp.getData(), dp.getOffset(), dp.getLength())+dp.getLength());
public static void main(String[] args) throws Exception {
InetSocketAddress loopbackEphemeral = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
Server server;
Thread serverThread;
try (var _ = server = new Server(loopbackEphemeral);
DatagramSocket ds = new DatagramSocket(loopbackEphemeral)) {
InetSocketAddress destAddr = server.getServerAddress();
// start the server
serverThread = new Thread(server);
serverThread.start();
byte[] b = new byte[100];
DatagramPacket dp = new DatagramPacket(b, b.length);
for (String msg : msgs) {
System.out.println("sending message from " + ds.getLocalSocketAddress()
+ " to " + destAddr);
ds.send(new DatagramPacket(msg.getBytes(), msg.length(), destAddr));
// wait for a reply from the server
ds.receive(dp);
System.out.println("received message from: " + dp.getAddress() + ":" + dp.getPort());
String actual = new String(dp.getData(), dp.getOffset(), dp.getLength());
if (!msg.equals(actual)) {
throw new RuntimeException("Msg expected: " + msg
+ " of length: " + msg.length() +
", actual received: " + actual + " of length: " + dp.getLength());
}
}
System.out.println("All " + msgs.length + " replies received from the server");
}
// wait for the server thread to complete
System.out.println("awaiting server thread " + serverThread + " to complete");
serverThread.join();
Exception serverFailure = server.serverFailure.get();
if (serverFailure != null) {
System.err.println("Unexpected failure on server: " + serverFailure);
throw serverFailure;
}
ds.close();
System.out.println("Test Passed!!!");
}
}