undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,207 @@
/*
* Copyright (c) 2001, 2018, 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.
*/
/* @test
* @bug 8156002 8201474
* @summary Unit test for socket-channel adaptors
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
* @run main AdaptSocket
*/
import java.io.*;
import java.net.*;
import java.nio.channels.*;
import java.util.Arrays;
public class AdaptSocket {
static final java.io.PrintStream out = System.out;
static void test(TestServers.AbstractServer server,
int timeout,
boolean shouldTimeout)
throws Exception
{
out.println();
InetSocketAddress isa = new InetSocketAddress(server.getAddress(), server.getPort());
SocketChannel sc = SocketChannel.open();
Socket so = sc.socket();
out.println("opened: " + so);
out.println(" " + sc);
//out.println("opts: " + sc.options());
so.setTcpNoDelay(true);
//so.setTrafficClass(SocketOpts.IP.TOS_THROUGHPUT);
so.setKeepAlive(true);
so.setSoLinger(true, 42);
so.setOOBInline(true);
so.setReceiveBufferSize(512);
so.setSendBufferSize(512);
//out.println(" " + sc.options());
if (timeout == 0)
so.connect(isa);
else {
try {
so.connect(isa, timeout);
} catch (SocketTimeoutException x) {
if (shouldTimeout) {
out.println("Connection timed out, as expected");
return;
} else {
throw x;
}
}
}
out.println("connected: " + so);
out.println(" " + sc);
byte[] bb = new byte[100];
int n = so.getInputStream().read(bb);
String s = new String(bb, 0, n - 2, "US-ASCII");
out.println(isa + " says: \"" + s + "\"");
so.shutdownInput();
out.println("ishut: " + sc);
so.shutdownOutput();
out.println("oshut: " + sc);
so.close();
out.println("closed: " + so);
out.println(" " + sc);
}
static String dataString = "foo\r\n";
static void testRead(Socket so, boolean shouldTimeout)
throws Exception
{
String data = "foo\r\n";
so.getOutputStream().write(dataString.getBytes("US-ASCII"));
InputStream is = so.getInputStream();
try {
byte[] b = new byte[100];
int n = is.read(b);
if (shouldTimeout) {
throw new Exception("Should time out, but not, data: " + Arrays.toString(b));
}
if (n != 5) {
throw new Exception("Incorrect number of bytes read: " + n);
}
if (!dataString.equals(new String(b, 0, n, "US-ASCII"))) {
throw new Exception("Incorrect data read: " + n);
}
} catch (SocketTimeoutException x) {
if (shouldTimeout) {
out.println("Read timed out, as expected");
return;
}
throw x;
}
}
static void testRead(TestServers.EchoServer echoServer,
int timeout,
boolean shouldTimeout)
throws Exception
{
out.println();
InetSocketAddress isa
= new InetSocketAddress(echoServer.getAddress(),
echoServer.getPort());
SocketChannel sc = SocketChannel.open();
sc.connect(isa);
Socket so = sc.socket();
out.println("connected: " + so);
out.println(" " + sc);
if (timeout > 0)
so.setSoTimeout(timeout);
out.println("timeout: " + so.getSoTimeout());
testRead(so, shouldTimeout);
for (int i = 0; i < 4; i++) {
out.println("loop: " + i);
testRead(so, shouldTimeout);
}
sc.close();
}
static void testConnect(TestServers.AbstractServer server,
int timeout,
boolean shouldFail)
throws Exception
{
SocketAddress sa = new InetSocketAddress(server.getAddress(), server.getPort());
try (SocketChannel sc = SocketChannel.open()) {
Socket s = sc.socket();
try {
if (timeout > 0) {
s.connect(sa, timeout);
} else {
s.connect(sa);
}
if (shouldFail)
throw new Exception("Connection should not be established");
} catch (SocketException se) {
if (!shouldFail)
throw se;
out.println("connect failed as expected: " + se);
}
}
}
public static void main(String[] args) throws Exception {
try (TestServers.DayTimeServer dayTimeServer
= TestServers.DayTimeServer.startNewServer()) {
test(dayTimeServer, 0, false);
test(dayTimeServer, 1000, false);
}
try (TestServers.DayTimeServer lingerDayTimeServer
= TestServers.DayTimeServer.startNewServer(100)) {
// this test no longer really test the connection timeout
// since there is no way to prevent the server from eagerly
// accepting connection...
test(lingerDayTimeServer, 10, true);
}
try (TestServers.EchoServer echoServer
= TestServers.EchoServer.startNewServer()) {
testRead(echoServer, 0, false);
testRead(echoServer, 8000, false);
}
try (TestServers.NoResponseServer noResponseServer
= TestServers.NoResponseServer.startNewServer()) {
testRead(noResponseServer, 10, true);
}
TestServers.RefusingServer refuser = TestServers.RefusingServer.newRefusingServer();
testConnect(refuser, 0, true);
testConnect(refuser, 10000, true);
}
}

View file

@ -0,0 +1,522 @@
/*
* Copyright (c) 2019, 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.
*/
/* @test
* @bug 8222774 4430139
* @run testng AdaptorStreams
* @summary Exercise socket adaptor input/output streams
*/
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test
public class AdaptorStreams {
/**
* Test read when bytes are available
*/
public void testRead1() throws Exception {
withConnection((sc, peer) -> {
peer.getOutputStream().write(99);
int n = sc.socket().getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test read blocking before bytes are available
*/
public void testRead2() throws Exception {
withConnection((sc, peer) -> {
scheduleWrite(peer.getOutputStream(), 99, 1000);
int n = sc.socket().getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test read when peer has closed connection
*/
public void testRead3() throws Exception {
withConnection((sc, peer) -> {
peer.close();
int n = sc.socket().getInputStream().read();
assertEquals(n, -1);
});
}
/**
* Test read blocking before peer closes connection
*/
public void testRead4() throws Exception {
withConnection((sc, peer) -> {
scheduleClose(peer, 1000);
int n = sc.socket().getInputStream().read();
assertEquals(n, -1);
});
}
/**
* Test async close of socket when thread blocked in read
*/
public void testRead5() throws Exception {
withConnection((sc, peer) -> {
scheduleClose(sc, 2000);
InputStream in = sc.socket().getInputStream();
expectThrows(IOException.class, () -> in.read());
});
}
/**
* Test interrupted status set before read
*/
public void testRead6() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
Thread.currentThread().interrupt();
try {
InputStream in = s.getInputStream();
expectThrows(IOException.class, () -> in.read());
} finally {
Thread.interrupted(); // clear interrupt
}
assertTrue(s.isClosed());
});
}
/**
* Test interrupt of thread blocked in read
*/
public void testRead7() throws Exception {
withConnection((sc, peer) -> {
Future<?> interrupter = scheduleInterrupt(Thread.currentThread(), 2000);
Socket s = sc.socket();
try {
InputStream in = s.getInputStream();
expectThrows(IOException.class, () -> in.read());
} finally {
interrupter.cancel(true);
Thread.interrupted(); // clear interrupt
}
assertTrue(s.isClosed());
});
}
/**
* Test read when channel is configured non-blocking
*/
public void testRead8() throws Exception {
withConnection((sc, peer) -> {
sc.configureBlocking(false);
InputStream in = sc.socket().getInputStream();
expectThrows(IllegalBlockingModeException.class, () -> in.read());
});
}
/**
* Test timed read when bytes are available
*/
public void testTimedRead1() throws Exception {
withConnection((sc, peer) -> {
peer.getOutputStream().write(99);
Socket s = sc.socket();
s.setSoTimeout(60_000);
int n = s.getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test timed read blocking before bytes are available
*/
public void testTimedRead2() throws Exception {
withConnection((sc, peer) -> {
scheduleWrite(peer.getOutputStream(), 99, 1000);
Socket s = sc.socket();
s.setSoTimeout(60_000);
int n = s.getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test timed read when the read times out
*/
public void testTimedRead3() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
s.setSoTimeout(500);
InputStream in = s.getInputStream();
expectThrows(SocketTimeoutException.class, () -> in.read());
});
}
/**
* Test async close of socket when thread blocked in timed read
*/
public void testTimedRead4() throws Exception {
withConnection((sc, peer) -> {
scheduleClose(sc, 2000);
Socket s = sc.socket();
s.setSoTimeout(60_000);
InputStream in = s.getInputStream();
expectThrows(IOException.class, () -> in.read());
});
}
/**
* Test interrupted status set before timed read
*/
public void testTimedRead5() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
Thread.currentThread().interrupt();
try {
s.setSoTimeout(60_000);
InputStream in = s.getInputStream();
expectThrows(IOException.class, () -> in.read());
} finally {
Thread.interrupted(); // clear interrupt
}
assertTrue(s.isClosed());
});
}
/**
* Test interrupt of thread blocked in timed read
*/
public void testTimedRead6() throws Exception {
withConnection((sc, peer) -> {
Future<?> interrupter = scheduleInterrupt(Thread.currentThread(), 2000);
Socket s = sc.socket();
try {
s.setSoTimeout(60_000);
InputStream in = s.getInputStream();
expectThrows(IOException.class, () -> in.read());
assertTrue(s.isClosed());
} finally {
interrupter.cancel(true);
Thread.interrupted(); // clear interrupt
}
assertTrue(s.isClosed());
});
}
/**
* Test async close of socket when thread blocked in write
*/
public void testWrite1() throws Exception {
withConnection((sc, peer) -> {
scheduleClose(sc, 2000);
expectThrows(IOException.class, () -> {
OutputStream out = sc.socket().getOutputStream();
byte[] data = new byte[64*1000];
while (true) {
out.write(data);
}
});
});
}
/**
* Test interrupted status set before write
*/
public void testWrite2() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
Thread.currentThread().interrupt();
try {
OutputStream out = s.getOutputStream();
expectThrows(IOException.class, () -> out.write(99));
} finally {
Thread.interrupted(); // clear interrupt
}
assertTrue(s.isClosed());
});
}
/**
* Test interrupt of thread blocked in write
*/
public void testWrite3() throws Exception {
withConnection((sc, peer) -> {
Future<?> interrupter = scheduleInterrupt(Thread.currentThread(), 2000);
Socket s = sc.socket();
try {
expectThrows(IOException.class, () -> {
OutputStream out = sc.socket().getOutputStream();
byte[] data = new byte[64*1000];
while (true) {
out.write(data);
}
});
} finally {
interrupter.cancel(true);
Thread.interrupted(); // clear interrupt
}
assertTrue(s.isClosed());
});
}
/**
* Test write when channel is configured non-blocking
*/
public void testWrite4() throws Exception {
withConnection((sc, peer) -> {
sc.configureBlocking(false);
OutputStream out = sc.socket().getOutputStream();
expectThrows(IllegalBlockingModeException.class, () -> out.write(99));
});
}
/**
* Test read when there are bytes available and another thread is blocked
* in write
*/
public void testConcurrentReadWrite1() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
// block thread in write
execute(() -> {
var data = new byte[64*1024];
OutputStream out = s.getOutputStream();
for (;;) {
out.write(data);
}
});
Thread.sleep(1000); // give writer time to block
// test read when bytes are available
peer.getOutputStream().write(99);
int n = s.getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test read blocking when another thread is blocked in write
*/
public void testConcurrentReadWrite2() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
// block thread in write
execute(() -> {
var data = new byte[64*1024];
OutputStream out = s.getOutputStream();
for (;;) {
out.write(data);
}
});
Thread.sleep(1000); // give writer time to block
// test read blocking until bytes are available
scheduleWrite(peer.getOutputStream(), 99, 500);
int n = s.getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test writing when another thread is blocked in read
*/
public void testConcurrentReadWrite3() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
// block thread in read
execute(() -> {
s.getInputStream().read();
});
Thread.sleep(100); // give reader time to block
// test write
s.getOutputStream().write(99);
int n = peer.getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test timed read when there are bytes available and another thread is
* blocked in write
*/
public void testConcurrentTimedReadWrite1() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
// block thread in write
execute(() -> {
var data = new byte[64*1024];
OutputStream out = s.getOutputStream();
for (;;) {
out.write(data);
}
});
Thread.sleep(1000); // give writer time to block
// test read when bytes are available
peer.getOutputStream().write(99);
s.setSoTimeout(60_000);
int n = s.getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test timed read blocking when another thread is blocked in write
*/
public void testConcurrentTimedReadWrite2() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
// block thread in write
execute(() -> {
var data = new byte[64*1024];
OutputStream out = s.getOutputStream();
for (;;) {
out.write(data);
}
});
Thread.sleep(1000); // give writer time to block
// test read blocking until bytes are available
scheduleWrite(peer.getOutputStream(), 99, 500);
s.setSoTimeout(60_000);
int n = s.getInputStream().read();
assertEquals(n, 99);
});
}
/**
* Test writing when another thread is blocked in read
*/
public void testConcurrentTimedReadWrite3() throws Exception {
withConnection((sc, peer) -> {
Socket s = sc.socket();
// block thread in read
execute(() -> {
s.setSoTimeout(60_000);
s.getInputStream().read();
});
Thread.sleep(100); // give reader time to block
// test write
s.getOutputStream().write(99);
int n = peer.getInputStream().read();
assertEquals(n, 99);
});
}
// -- test infrastructure --
interface ThrowingTask {
void run() throws Exception;
}
interface ThrowingBiConsumer<T, U> {
void accept(T t, U u) throws Exception;
}
/**
* Invokes the consumer with a connected pair of socket channel and socket
*/
static void withConnection(ThrowingBiConsumer<SocketChannel, Socket> consumer)
throws Exception
{
var loopback = InetAddress.getLoopbackAddress();
try (ServerSocket ss = new ServerSocket()) {
ss.bind(new InetSocketAddress(loopback, 0));
try (SocketChannel sc = SocketChannel.open(ss.getLocalSocketAddress())) {
try (Socket peer = ss.accept()) {
consumer.accept(sc, peer);
}
}
}
}
static Future<?> scheduleWrite(OutputStream out, byte[] data, long delay) {
return schedule(() -> {
try {
out.write(data);
} catch (IOException ioe) { }
}, delay);
}
static Future<?> scheduleWrite(OutputStream out, int b, long delay) {
return scheduleWrite(out, new byte[] { (byte)b }, delay);
}
static Future<?> scheduleClose(Closeable c, long delay) {
return schedule(() -> {
try {
c.close();
} catch (IOException ioe) { }
}, delay);
}
static Future<?> scheduleInterrupt(Thread t, long delay) {
return schedule(() -> t.interrupt(), delay);
}
static Future<?> schedule(Runnable task, long delay) {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
try {
return executor.schedule(task, delay, TimeUnit.MILLISECONDS);
} finally {
executor.shutdown();
}
}
static Future<?> execute(ThrowingTask task) {
ExecutorService pool = Executors.newFixedThreadPool(1);
try {
return pool.submit(() -> {
task.run();
return null;
});
} finally {
pool.shutdown();
}
}
}

View file

@ -0,0 +1,260 @@
/*
* Copyright (c) 2006, 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.
*/
/* @test
* @bug 6285901 6501089
* @summary Check no data is written to wrong socket channel during async closing.
* @requires (os.family != "windows")
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;
public class AsyncCloseChannel {
static volatile boolean failed = false;
static volatile boolean keepGoing = true;
static int maxAcceptCount = 100;
static volatile int acceptCount = 0;
static int sensorPort;
static int targetPort;
public static void main(String args[]) throws Exception {
Thread ss = new SensorServer(); ss.start();
Thread ts = new TargetServer(); ts.start();
sensorPort = ((ServerThread)ss).server.getLocalPort();
targetPort = ((ServerThread)ts).server.getLocalPort();
Thread sc = new SensorClient(); sc.start();
Thread tc = new TargetClient(); tc.start();
while(acceptCount < maxAcceptCount && !failed) {
Thread.sleep(10);
}
keepGoing = false;
try {
ss.interrupt();
ts.interrupt();
sc.interrupt();
tc.interrupt();
} catch (Exception e) {}
if (failed)
throw new RuntimeException("AsyncCloseChannel2 failed after <"
+ acceptCount + "> times of accept!");
}
static class SensorServer extends ServerThread {
public void runEx() throws Exception {
while(keepGoing) {
try {
final Socket s = server.accept();
new Thread() {
public void run() {
try {
int c = s.getInputStream().read();
if(c != -1) {
// No data is ever written to the peer's socket!
System.err.println("Oops: read a character: "
+ (char) c);
failed = true;
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
closeIt(s);
}
}
}.start();
} catch (IOException ex) {
System.err.println("Exception on sensor server " + ex.getMessage());
}
}
}
}
static class TargetServer extends ServerThread {
public void runEx() throws Exception {
while (keepGoing) {
try {
final Socket s = server.accept();
acceptCount++;
new Thread() {
public void run() {
boolean empty = true;
try {
while (keepGoing) {
int c = s.getInputStream().read();
if(c == -1) {
if(!empty)
break;
}
empty = false;
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
closeIt(s);
}
}
}.start();
} catch (IOException ex) {
System.err.println("Exception on target server " + ex.getMessage());
}
}
}
}
static class SensorClient extends Thread {
private static boolean wake;
private static SensorClient theClient;
public void run() {
while (keepGoing) {
Socket s = null;
try {
s = new Socket();
synchronized(this) {
while(!wake && keepGoing) {
try {
wait();
} catch (InterruptedException ex) { }
}
wake = false;
}
s.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), sensorPort));
try {
Thread.sleep(10);
} catch (InterruptedException ex) { }
} catch (IOException ex) {
System.err.println("Exception on sensor client " + ex.getMessage());
} finally {
if(s != null) {
try {
s.close();
} catch(IOException ex) { ex.printStackTrace();}
}
}
}
}
public SensorClient() {
theClient = this;
}
public static void wakeMe() {
synchronized(theClient) {
wake = true;
theClient.notify();
}
}
}
static class TargetClient extends Thread {
volatile boolean ready = false;
public void run() {
while(keepGoing) {
try {
final SocketChannel s = SocketChannel.open(
new InetSocketAddress(InetAddress.getLoopbackAddress(), targetPort));
s.finishConnect();
s.socket().setSoLinger(false, 0);
ready = false;
Thread t = new Thread() {
public void run() {
ByteBuffer b = ByteBuffer.allocate(1);
try {
for(;;) {
b.clear();
b.put((byte) 'A');
b.flip();
s.write(b);
ready = true;
}
} catch (IOException ex) {
if(!(ex instanceof ClosedChannelException))
System.err.println("Exception in target client child "
+ ex.toString());
}
}
};
t.start();
while(!ready && keepGoing) {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {}
}
s.close();
SensorClient.wakeMe();
t.join();
} catch (IOException ex) {
System.err.println("Exception in target client parent "
+ ex.getMessage());
} catch (InterruptedException ex) {}
}
}
}
static abstract class ServerThread extends Thread {
ServerSocket server;
public ServerThread() {
super();
try {
server = new ServerSocket(0);
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void interrupt() {
super.interrupt();
if (server != null) {
try {
server.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void run() {
try {
runEx();
} catch (Exception ex) {
ex.printStackTrace();
}
}
abstract void runEx() throws Exception;
}
public static void closeIt(Socket s) {
try {
if(s != null)
s.close();
} catch (IOException ex) { }
}
}

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2000, 2018, 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.
*/
/* @test
* @summary Unit test for socket channels
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
* @run main Basic
*/
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
public class Basic {
static java.io.PrintStream out = System.out;
static void test(TestServers.DayTimeServer daytimeServer) throws Exception {
InetSocketAddress isa
= new InetSocketAddress(daytimeServer.getAddress(),
daytimeServer.getPort());
SocketChannel sc = SocketChannel.open(isa);
out.println("opened: " + sc);
/*
out.println("opts: " + sc.options());
((SocketOpts.IP.TCP)sc.options())
.noDelay(true)
.typeOfService(SocketOpts.IP.TOS_THROUGHPUT)
.broadcast(true)
.keepAlive(true)
.linger(42)
.outOfBandInline(true)
.receiveBufferSize(128)
.sendBufferSize(128)
.reuseAddress(true);
out.println(" " + sc.options());
*/
// sc.connect(isa);
out.println("connected: " + sc);
ByteBuffer bb = ByteBuffer.allocateDirect(100);
int n = sc.read(bb);
bb.position(bb.position() - 2); // Drop CRLF
bb.flip();
CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
out.println(isa + " says: \"" + cb + "\"");
sc.socket().shutdownInput();
out.println("ishut: " + sc);
sc.socket().shutdownOutput();
out.println("oshut: " + sc);
sc.close();
out.println("closed: " + sc);
}
public static void main(String[] args) throws Exception {
try (TestServers.DayTimeServer dayTimeServer
= TestServers.DayTimeServer.startNewServer(100)) {
test(dayTimeServer);
}
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2003, 2020, 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.
*/
/* @test
* @requires os.family == "Linux"
* @bug 4863423
* @summary Test Util caching policy
*/
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class BigReadWrite {
static int testSize = 15;
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("/dev/zero");
FileChannel fc = fos.getChannel();
// Three small writes to fill up the Util cache
ByteBuffer buf = ByteBuffer.allocate(900);
fc.write(buf);
buf = ByteBuffer.allocate(950);
fc.write(buf);
buf = ByteBuffer.allocate(975);
fc.write(buf);
buf = ByteBuffer.allocate(4419000);
// Now initiate large write to create larger direct buffers
long iterations = 0;
while (iterations < 50) {
fc.write(buf);
buf.rewind();
iterations++;
}
// Clean up
fc.close();
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2010, 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.
*/
/* @test
* @bug 4774315
* @summary Test if bind problems cause BindException not SocketException
*/
import java.net.*;
import java.nio.channels.*;
public class Bind {
public static void main(String[] args) throws Exception {
SocketChannel sc1 = SocketChannel.open();
try {
sc1.bind(new InetSocketAddress(0));
int port = sc1.socket().getLocalPort();
SocketChannel sc2 = SocketChannel.open();
try {
sc2.bind(new InetSocketAddress(port));
} finally {
sc2.close();
}
} catch (BindException be) {
// Correct result
} finally {
sc1.close();
}
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2002, 2012, 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.
*/
/* @test
* @bug 4514230
* @summary Test setting illegal buffer sizes
* @library ..
*/
import java.nio.channels.*;
public class BufferSize {
public static void main(String[] args) throws Exception {
ServerSocketChannel sc = ServerSocketChannel.open();
try {
sc.socket().setReceiveBufferSize(-1);
throw new Exception("Illegal size accepted");
} catch (IllegalArgumentException iae) {
// correct behavior
}
try {
sc.socket().setReceiveBufferSize(0);
throw new Exception("Illegal size accepted");
} catch (IllegalArgumentException iae) {
// correct behavior
}
sc.close();
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2001, 2010, 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.
*/
/* @test
* @bug 4458266
*/
import java.io.IOException;
import java.net.*;
import java.nio.channels.*;
public class Close {
static SelectionKey open() throws IOException {
SocketChannel sc = SocketChannel.open();
Selector sel = Selector.open();
sc.configureBlocking(false);
return sc.register(sel, SelectionKey.OP_READ);
}
static void check(SelectionKey sk) throws IOException {
if (sk.isValid())
throw new RuntimeException("Key still valid");
if (sk.channel().isOpen())
throw new RuntimeException("Channel still open");
// if (!((SocketChannel)sk.channel()).socket().isClosed())
// throw new RuntimeException("Socket still open");
}
static void testSocketClose() throws IOException {
SelectionKey sk = open();
//((SocketChannel)sk.channel()).socket().close();
check(sk);
}
static void testChannelClose() throws IOException {
SelectionKey sk = open();
try {
sk.channel().close();
check(sk);
} finally {
sk.selector().close();
}
}
public static void main(String[] args) throws Exception {
//## testSocketClose();
testChannelClose();
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2006, 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.
*/
/* @test
* @bug 6380091
*/
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.io.IOException;
public class CloseAfterConnect {
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(0));
InetAddress lh = InetAddress.getLocalHost();
final SocketChannel sc = SocketChannel.open();
final InetSocketAddress isa =
new InetSocketAddress(lh, ssc.socket().getLocalPort());
// establish connection in another thread
Runnable connector =
new Runnable() {
public void run() {
try {
sc.connect(isa);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
};
Thread thr = new Thread(connector);
thr.start();
// wait for connect to be established and for thread to
// terminate
do {
try {
thr.join();
} catch (InterruptedException x) { }
} while (thr.isAlive());
// check connection is established
if (!sc.isConnected()) {
throw new RuntimeException("SocketChannel not connected");
}
// close channel - this triggered the bug as it attempted to signal
// a thread that no longer exists
sc.close();
// clean-up
ssc.accept().close();
ssc.close();
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2018, 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.
*/
/* @test
* @bug 8198928
* @library /test/lib
* @build jdk.test.lib.Utils
* @run main/timeout=480 CloseDuringConnect
* @summary Attempt to cause a deadlock by closing a SocketChannel in one thread
* where another thread is closing the channel after a connect fail
*/
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.SocketChannel;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.IntStream;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import jdk.test.lib.Utils;
public class CloseDuringConnect {
// number of test iterations, needs to be 5-10 at least
static final int ITERATIONS = 50;
// maximum delay before closing SocketChannel, in milliseconds
static final int MAX_DELAY_BEFORE_CLOSE = 20;
/**
* Invoked by a task in the thread pool to connect to a remote address.
* The connection should never be established.
*/
static Void connect(SocketChannel sc, SocketAddress remote) {
try {
if (!sc.connect(remote)) {
while (!sc.finishConnect()) {
Thread.yield();
}
}
throw new RuntimeException("Connected, should not happen");
} catch (IOException expected) { }
if (sc.isConnected())
throw new RuntimeException("isConnected return true, should not happen");
return null;
}
/**
* Invoked by a task in the thread pool to close a socket channel.
*/
static Void close(SocketChannel sc) {
try {
sc.close();
} catch (IOException e) {
throw new UncheckedIOException("close failed", e);
}
return null;
}
/**
* Test for deadlock by submitting a task to connect to the given address
* while another task closes the socket channel.
* @param pool the thread pool to submit or schedule tasks
* @param remote the remote address, does not accept connections
* @param blocking socket channel blocking mode
* @param delay the delay, in millis, before closing the channel
*/
static void test(ScheduledExecutorService pool,
SocketAddress remote,
boolean blocking,
long delay) {
try {
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(blocking);
Future<Void> r1 = pool.submit(() -> connect(sc, remote));
Future<Void> r2 = pool.schedule(() -> close(sc), delay, MILLISECONDS);
r1.get();
r2.get();
} catch (Throwable t) {
throw new RuntimeException("Test failed", t);
}
}
public static void main(String[] args) throws Exception {
SocketAddress refusing = Utils.refusingEndpoint();
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
try {
IntStream.range(0, ITERATIONS).forEach(i -> {
System.out.format("Iteration %d ...%n", (i + 1));
// Execute the test for varying delays up to MAX_DELAY_BEFORE_CLOSE,
// for socket channels configured both blocking and non-blocking
IntStream.range(0, MAX_DELAY_BEFORE_CLOSE).forEach(delay -> {
test(pool, refusing, /*blocking mode*/true, delay);
test(pool, refusing, /*blocking mode*/false, delay);
});
});
} finally {
pool.shutdown();
}
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2012, 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.
*/
/* @test
* @summary Test asynchronous close during a blocking write
* @key randomness
*/
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.Random;
public class CloseDuringWrite {
static final Random rand = new Random();
/**
* A task that closes a Closeable
*/
static class Closer implements Callable<Void> {
final Closeable c;
Closer(Closeable c) {
this.c = c;
}
public Void call() throws IOException {
c.close();
return null;
}
}
public static void main(String[] args) throws Exception {
ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
try {
try (ServerSocketChannel ssc = ServerSocketChannel.open()) {
ssc.bind(new InetSocketAddress(0));
InetAddress lh = InetAddress.getLocalHost();
int port = ssc.socket().getLocalPort();
SocketAddress sa = new InetSocketAddress(lh, port);
ByteBuffer bb = ByteBuffer.allocate(2*1024*1024);
for (int i=0; i<20; i++) {
try (SocketChannel source = SocketChannel.open(sa);
SocketChannel sink = ssc.accept())
{
// schedule channel to be closed
Closer c = new Closer(source);
int when = 1000 + rand.nextInt(2000);
Future<Void> result = pool.schedule(c, when, TimeUnit.MILLISECONDS);
// the write should either succeed or else throw a
// ClosedChannelException (more likely an
// AsynchronousCloseException)
try {
for (;;) {
int limit = rand.nextInt(bb.capacity());
bb.position(0);
bb.limit(limit);
int n = source.write(bb);
System.out.format("wrote %d, expected %d%n", n, limit);
}
} catch (ClosedChannelException expected) {
System.out.println(expected + " (expected)");
} finally {
result.get();
}
}
}
}
} finally {
pool.shutdown();
}
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2005, 2020, 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.
*/
/* @test
@bug 4960962 6215050
@summary Test if the registered SocketChannel can be closed immediately
@run main/timeout=10 CloseRegisteredChannel
*/
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.*;
public class CloseRegisteredChannel {
public static void main(String[] args) throws Exception {
ServerSocketChannel server = ServerSocketChannel.open();
ServerSocket s = server.socket ();
s.bind (new InetSocketAddress (0));
int port = s.getLocalPort ();
//System.out.println ("listening on port " + port);
SocketChannel client = SocketChannel.open ();
client.connect (new InetSocketAddress (InetAddress.getLoopbackAddress(), port));
SocketChannel peer = server.accept();
peer.configureBlocking(true);
Selector selector = Selector.open ();
client.configureBlocking (false);
SelectionKey key = client.register (
selector, SelectionKey.OP_READ, null
);
client.close();
//System.out.println ("client.isOpen = " + client.isOpen());
System.out.println ("Will hang here...");
int nb = peer.read(ByteBuffer.allocate (1024));
//System.out.println("read nb=" + nb);
selector.close();
server.close();
}
}

View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2005, 2019, 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.
*/
/* @test
@bug 4726957 4724030 6232954
@summary Test if the SocketChannel with timeout set can be closed immediately
@run main/timeout=20 CloseTimeoutChannel
*/
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.net.*;
public class CloseTimeoutChannel {
public static void main(String args[]) throws Exception {
int port = -1;
try {
ServerSocketChannel listener=ServerSocketChannel.open();
listener.socket().bind(new InetSocketAddress(0));
port = listener.socket().getLocalPort();
AcceptorThread thread=new AcceptorThread(listener);
thread.start();
} catch (IOException e) {
System.out.println("Mysterious IO problem");
e.printStackTrace();
System.exit(1);
}
//Establish connection. Bug only happens if we open with channel.
try {
System.out.println("Establishing connection");
Socket socket=SocketChannel.open(
new InetSocketAddress(InetAddress.getLoopbackAddress(), port)).socket();
OutputStream out=socket.getOutputStream();
InputStream in=socket.getInputStream();
System.out.println("1. Writing byte 1");
out.write((byte)1);
int n=read(socket, in);
System.out.println("Read byte "+n+"\n");
System.out.println("3. Writing byte 3");
out.write((byte)3);
System.out.println("Closing");
socket.close();
} catch (IOException e) {
System.out.println("Mysterious IO problem");
e.printStackTrace();
System.exit(1);
}
}
/** Reads one byte from in, which must be s.getInputStream. */
private static int read(Socket s, InputStream in) throws IOException {
try {
s.setSoTimeout(8000); //causes a bug!
return in.read();
} finally {
s.setSoTimeout(0);
}
}
/** Server thread */
static class AcceptorThread extends Thread {
final String INDENT="\t\t\t\t";
ServerSocketChannel _listener;
/** @param listener MUST be bound to a port */
AcceptorThread(ServerSocketChannel listener) {
_listener=listener;
}
public void run() {
try {
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
System.out.println(INDENT+"Listening on port "+
_listener.socket().getLocalPort());
ByteBuffer buf=ByteBuffer.allocate(5);
Socket client=_listener.accept().socket();
System.out.println(INDENT+"Accepted client");
OutputStream out=client.getOutputStream();
InputStream in=client.getInputStream();
int n=in.read();
System.out.println(INDENT+"Read byte "+n+"\n");
System.out.println(INDENT+"2. Writing byte 2");
out.write((byte)2);
n=in.read();
System.out.println(INDENT+"Read byte "+n+"\n");
n=in.read();
System.out.println(INDENT+"Read byte "
+(n<0 ? "EOF" : Integer.toString(n)));
System.out.println(INDENT+"Closing");
client.close();
} catch (IOException e) {
System.out.println(INDENT+"Error accepting!");
} finally {
try { _listener.close(); } catch (IOException ignore) { }
}
}
}
}

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 2002, 2018, 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.
*/
/* @test
* @bug 4650679 8037360
* @summary Unit test for socket channels
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
* @run main Connect
*/
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class Connect {
private static final long INCREMENTAL_DELAY = 30L * 1000L;
public static void main(String args[]) throws Exception {
try (TestServers.EchoServer echoServer
= TestServers.EchoServer.startNewServer(1000)) {
test1(echoServer);
}
try {
test1(TestServers.RefusingServer.newRefusingServer());
throw new Exception("Refused connection throws no exception");
} catch (ConnectException ce) {
// Correct result
}
}
static void test1(TestServers.AbstractServer server) throws Exception {
Selector selector;
SocketChannel sc;
SelectionKey sk;
InetSocketAddress isa = new InetSocketAddress(
server.getAddress(), server.getPort());
sc = SocketChannel.open();
sc.configureBlocking(false);
selector = Selector.open();
sk = sc.register(selector, SelectionKey.OP_CONNECT);
if (sc.connect(isa)) {
System.err.println("Connected immediately!");
sc.close();
selector.close();
return;
} else {
ByteBuffer buf = ByteBuffer.allocateDirect(100);
buf.asCharBuffer().put(new String(
"The quick brown fox jumped over the lazy dog."
).toCharArray());
buf.flip();
long startTime = System.currentTimeMillis();
while(true) {
selector.select(INCREMENTAL_DELAY);
Set selectedKeys = selector.selectedKeys();
if(selectedKeys.isEmpty()) {
System.err.println("Elapsed time without response: " +
(System.currentTimeMillis() -
startTime) / 1000L + " seconds.");
}
else if(!selectedKeys.contains(sk))
{
System.err.println("Got wrong event about selection key.");
} else {
System.err.println("Got event for our selection key.");
if(sk.isConnectable()) {
if(sc.finishConnect()) {
if(sc.isConnected()) {
System.err.println("Successful connect.");
sk.interestOps(SelectionKey.OP_WRITE);
sc.write(buf);
} else {
System.err.println(
"Finish connect completed incorrectly.");
}
} else {
System.err.println(
"key incorrectly indicated socket channel connectable.");
}
}
if(sk.isWritable() && (buf.remaining() > 0)) {
sc.write(buf);
}
if(buf.remaining() == 0) {
System.err.println(
"SUCCESS! buffer contents were sent.");
sc.close();
selector.close();
return;
}
}
selectedKeys.clear();
}
}
}
}

View file

@ -0,0 +1,286 @@
/*
* Copyright (c) 2001, 2022, 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.
*/
/* @test
* @summary Test socket-channel connection-state transitions
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
* @run main ConnectState
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
public class ConnectState {
static PrintStream log = System.err;
static InetSocketAddress remote;
final static int ST_UNCONNECTED = 0;
final static int ST_PENDING = 1;
final static int ST_CONNECTED = 2;
final static int ST_CLOSED = 3;
final static int ST_PENDING_OR_CONNECTED = 4;
// NO exceptions expected
final static Collection<Class<?>> NONE = Collections.emptySet();
// make a set of expected exception.
static Collection<Class<?>> expectedExceptions(Class<?>... expected) {
final Collection<Class<?>> exceptions;
if (expected.length == 0) {
exceptions = NONE;
} else if (expected.length == 1) {
assert expected[0] != null;
exceptions = Collections.<Class<?>>singleton(expected[0]);
} else {
exceptions = new HashSet<>(Arrays.asList(expected));
}
return exceptions;
}
static abstract class Test {
abstract String go(SocketChannel sc) throws Exception;
static void check(boolean test, String desc) throws Exception {
if (!test)
throw new Exception("Incorrect state: " + desc);
}
static void check(SocketChannel sc, int state) throws Exception {
switch (state) {
case ST_UNCONNECTED:
check(!sc.isConnected(), "!isConnected");
check(!sc.isConnectionPending(), "!isConnectionPending");
check(sc.isOpen(), "isOpen");
break;
case ST_PENDING:
check(!sc.isConnected(), "!isConnected");
check(sc.isConnectionPending(), "isConnectionPending");
check(sc.isOpen(), "isOpen");
break;
case ST_CONNECTED:
check(sc.isConnected(), "isConnected");
check(!sc.isConnectionPending(), "!isConnectionPending");
check(sc.isOpen(), "isOpen");
break;
case ST_CLOSED:
check(sc.isConnected(), "isConnected");
check(!sc.isConnectionPending(), "!isConnectionPending");
check(sc.isOpen(), "isOpen");
break;
case ST_PENDING_OR_CONNECTED:
check(sc.isConnected() || sc.isConnectionPending(),
"isConnected || isConnectionPending");
check(sc.isOpen(), "isOpen");
break;
}
}
Test(String name, Class<?> exception, int state) throws Exception {
this(name, expectedExceptions(exception), state);
}
// On some architecture we may need to accept several exceptions.
// For instance on Solaris, when using a server colocated on the
// machine we cannot guarantee that we will get a
// ConnectionPendingException when connecting twice on the same
// non-blocking socket. We may instead get an
// AlreadyConnectedException, which is also valid: it simply means
// that the first connection has been immediately accepted.
Test(String name, Collection<Class<?>> exceptions, int state)
throws Exception {
SocketChannel sc = SocketChannel.open();
String note;
try {
try {
note = go(sc);
} catch (Exception x) {
Class<?> expectedExceptionClass = null;
for (Class<?> exception : exceptions) {
if (exception.isInstance(x)) {
log.println(name + ": As expected: "
+ x);
expectedExceptionClass = exception;
check(sc, state);
break;
}
}
if (expectedExceptionClass == null
&& !exceptions.isEmpty()) {
// we had an exception, but it's not of the set of
// exceptions we expected.
throw new Exception(name
+ ": Incorrect exception",
x);
} else if (exceptions.isEmpty()) {
// we didn't expect any exception
throw new Exception(name
+ ": Unexpected exception",
x);
}
// if we reach here, we have our expected exception
assert expectedExceptionClass != null;
return;
}
if (!exceptions.isEmpty()) {
throw new Exception(name
+ ": Expected exception not thrown: "
+ exceptions.iterator().next());
}
check(sc, state);
log.println(name + ": Returned normally"
+ ((note != null) ? ": " + note : ""));
} finally {
if (sc.isOpen())
sc.close();
}
}
}
static void tests() throws Exception {
log.println(remote);
new Test("Read unconnected", NotYetConnectedException.class,
ST_UNCONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
ByteBuffer b = ByteBuffer.allocateDirect(1024);
sc.read(b);
return null;
}};
new Test("Write unconnected", NotYetConnectedException.class,
ST_UNCONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
ByteBuffer b = ByteBuffer.allocateDirect(1024);
sc.write(b);
return null;
}};
new Test("Simple connect", NONE, ST_CONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.connect(remote);
return null;
}};
new Test("Simple connect & finish", NONE, ST_CONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.connect(remote);
if (!sc.finishConnect())
throw new Exception("finishConnect returned false");
return null;
}};
new Test("Double connect",
AlreadyConnectedException.class, ST_CONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.connect(remote);
sc.connect(remote);
return null;
}};
new Test("Finish w/o start",
NoConnectionPendingException.class, ST_UNCONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.finishConnect();
return null;
}};
// Note: using our local EchoServer rather than echo on a distant
// host - we see that Tries to finish = 0 (instead of ~ 18).
new Test("NB simple connect", NONE, ST_CONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.configureBlocking(false);
sc.connect(remote);
int n = 0;
while (!sc.finishConnect()) {
Thread.sleep(10);
n++;
}
sc.finishConnect(); // Check redundant invocation
return ("Tries to finish = " + n);
}};
// Note: using our local EchoServer rather than echo on a distant
// host - we cannot guarantee that this test will get a
// a ConnectionPendingException: it may get an
// AlreadyConnectedException, so we should allow for both.
new Test("NB double connect",
expectedExceptions(ConnectionPendingException.class,
AlreadyConnectedException.class),
ST_PENDING_OR_CONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.configureBlocking(false);
sc.connect(remote);
sc.connect(remote);
return null;
}};
new Test("NB finish w/o start",
NoConnectionPendingException.class, ST_UNCONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.configureBlocking(false);
sc.finishConnect();
return null;
}};
new Test("NB connect, B finish", NONE, ST_CONNECTED) {
@Override
String go(SocketChannel sc) throws Exception {
sc.configureBlocking(false);
sc.connect(remote);
sc.configureBlocking(true);
sc.finishConnect();
return null;
}};
}
public static void main(String[] args) throws Exception {
try (TestServers.EchoServer echoServer
= TestServers.EchoServer.startNewServer(500)) {
remote = new InetSocketAddress(echoServer.getAddress(),
echoServer.getPort());
tests();
}
}
}

View file

@ -0,0 +1,146 @@
/*
* Copyright (c) 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
* 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 java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
/*
* @test
* @bug 8376290
* @summary Verify that when a SocketChannel is registered with a Selector
* with an interest in CONNECT operation, then SocketChannel.finishConnect()
* throws the correct exception message, if the connect() fails
* @run junit/othervm -Djdk.includeInExceptions=hostInfoExclSocket ${test.main.class}
* @run junit/othervm -Djdk.includeInExceptions=hostInfo -Dcheck.relaxed=true ${test.main.class}
*/
class ConnectionRefusedMessage {
/*
* On a non-blocking SocketChannel, registered with a Selector, this test method
* attempts a SocketChannel.connect() against an address that is expected to return
* Connection refused. The test then calls SocketChannel.finishConnect() when the
* Selector makes available the ready key for this connect operation and expects
* that finishConnect() throws a ConnectException with the expected exception message.
*/
@Test
void testFinishConnect() throws Exception {
// find a suitable address against which the connect() attempt
// will result in a Connection refused exception
final InetSocketAddress destAddr = findSuitableRefusedAddress();
// skip the test if we couldn't find a port which would raise a connection refused error
assumeTrue(destAddr != null,
"couldn't find a suitable port which will generate a connection refused error");
try (Selector selector = Selector.open();
SocketChannel sc = SocketChannel.open()) {
// non-blocking
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_CONNECT);
System.err.println("establishing connection to " + destAddr);
boolean connected;
try {
connected = sc.connect(destAddr);
} catch (ConnectException ce) {
// Connect failed immediately, which is OK.
System.err.println("SocketChannel.connect() threw ConnectException - " + ce);
assertExceptionMessage(ce);
return; // nothing more to test
}
// this test checks the exception message of a ConnectException, so it's
// OK to skip the test if something unexpectedly accepted the connection
assumeFalse(connected, "unexpectedly connected to " + destAddr);
// wait for ready ops
int numReady = selector.select(Duration.ofMinutes(10).toMillis());
System.err.println("Num ready keys = " + numReady);
for (SelectionKey readyKey : selector.selectedKeys()) {
System.err.println("ready key: " + readyKey);
assertTrue(readyKey.isConnectable(), "unexpected key, readyOps = "
+ readyKey.readyOps());
readyKey.cancel();
try {
boolean success = sc.finishConnect();
// this test checks the exception message of a ConnectException, so it's
// OK to skip the test if something unexpectedly accepted the connection
assumeFalse(success, "unexpectedly connected to " + destAddr);
// this test doesn't expect finishConnect() to return normally
// with a return value of false
fail("ConnectException was not thrown");
} catch (ConnectException ce) {
System.err.println("got (expected) ConnectException from " +
"SocketChannel.finishConnect() - " + ce);
// verify exception message
assertExceptionMessage(ce);
}
}
}
}
private static void assertExceptionMessage(final ConnectException ce) {
if ("Connection refused".equals(ce.getMessage())) {
return;
}
if (Boolean.getBoolean("check.relaxed") && ce.getMessage() != null && ce.getMessage().startsWith("Connection refused")) {
return;
}
// propagate the original exception
fail("unexpected exception message: " + ce.getMessage(), ce);
}
// Try to find a suitable port to provoke a "Connection Refused" error.
private static InetSocketAddress findSuitableRefusedAddress() throws IOException {
final InetAddress loopbackAddr = InetAddress.getLoopbackAddress();
// Ports 47, 51, 61 are in the IANA reserved port list, and
// are currently unassigned to any specific service.
// We use them here on the assumption that there won't be
// any service listening on them.
InetSocketAddress destAddr = new InetSocketAddress(loopbackAddr, 47);
try (SocketChannel sc1 = SocketChannel.open(destAddr)) {
// we managed to connect (unexpectedly), let's try the next reserved port
destAddr = new InetSocketAddress(loopbackAddr, 51);
try (SocketChannel sc2 = SocketChannel.open(destAddr)) {
}
// we managed to connect (unexpectedly again), let's try the next reserved port
// as a last attempt
destAddr = new InetSocketAddress(loopbackAddr, 61);
try (SocketChannel sc3 = SocketChannel.open(destAddr)) {
}
return null;
} catch (ConnectException x) {
}
// the address which will generate a connection refused, when a connection is attempted
return destAddr;
}
}

View file

@ -0,0 +1,247 @@
/*
* Copyright (c) 2019, 2020, 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.
*/
/**
* @test
* @run testng ConnectionReset
* @summary Test behavior of SocketChannel.read and the Socket adaptor read
* and available methods when a connection is reset
*/
import java.io.InputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.lang.reflect.Method;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test
public class ConnectionReset {
static final int REPEAT_COUNT = 5;
/**
* Tests SocketChannel.read when the connection is reset and there are no
* bytes to read.
*/
public void testSocketChannelReadNoData() throws IOException {
System.out.println("testSocketChannelReadNoData");
withResetConnection(null, sc -> {
ByteBuffer bb = ByteBuffer.allocate(100);
for (int i=0; i<REPEAT_COUNT; i++) {
try {
sc.read(bb);
assertTrue(false);
} catch (IOException ioe) {
System.out.format("read => %s (expected)%n", ioe);
}
}
});
}
/**
* Tests SocketChannel.read when the connection is reset and there are bytes
* to read.
*/
public void testSocketChannelReadData() throws IOException {
System.out.println("testSocketChannelReadData");
byte[] data = { 1, 2, 3 };
withResetConnection(data, sc -> {
int remaining = data.length;
ByteBuffer bb = ByteBuffer.allocate(remaining + 100);
for (int i=0; i<REPEAT_COUNT; i++) {
try {
int bytesRead = sc.read(bb);
if (bytesRead == -1) {
System.out.println("read => EOF");
} else {
System.out.println("read => " + bytesRead + " byte(s)");
}
assertTrue(bytesRead > 0);
remaining -= bytesRead;
assertTrue(remaining >= 0);
} catch (IOException ioe) {
System.out.format("read => %s%n", ioe);
remaining = 0;
}
}
});
}
/**
* Tests available before Socket read when the connection is reset and there
* are no bytes to read.
*/
public void testAvailableBeforeSocketReadNoData() throws IOException {
System.out.println("testAvailableBeforeSocketReadNoData");
withResetConnection(null, sc -> {
Socket s = sc.socket();
InputStream in = s.getInputStream();
for (int i=0; i<REPEAT_COUNT; i++) {
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable == 0);
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
} else {
System.out.println("read => 1 byte");
}
assertTrue(false);
} catch (IOException ioe) {
System.out.format("read => %s (expected)%n", ioe);
}
}
});
}
/**
* Tests available before Socket read when the connection is reset and there
* are bytes to read.
*/
public void testAvailableBeforeSocketReadData() throws IOException {
System.out.println("testAvailableBeforeSocketReadData");
byte[] data = { 1, 2, 3 };
withResetConnection(data, sc -> {
Socket s = sc.socket();
InputStream in = s.getInputStream();
int remaining = data.length;
for (int i=0; i<REPEAT_COUNT; i++) {
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable <= remaining);
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
assertTrue(false);
} else {
System.out.println("read => 1 byte");
assertTrue(remaining > 0);
remaining--;
}
} catch (IOException ioe) {
System.out.format("read => %s%n", ioe);
remaining = 0;
}
}
});
}
/**
* Tests Socket read before available when the connection is reset and there
* are no bytes to read.
*/
public void testSocketReadNoDataBeforeAvailable() throws IOException {
System.out.println("testSocketReadNoDataBeforeAvailable");
withResetConnection(null, sc -> {
Socket s = sc.socket();
InputStream in = s.getInputStream();
for (int i=0; i<REPEAT_COUNT; i++) {
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
} else {
System.out.println("read => 1 byte");
}
assertTrue(false);
} catch (IOException ioe) {
System.out.format("read => %s (expected)%n", ioe);
}
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable == 0);
}
});
}
/**
* Tests Socket read before available when the connection is reset and there
* are bytes to read.
*/
public void testSocketReadDataBeforeAvailable() throws IOException {
System.out.println("testSocketReadDataBeforeAvailable");
byte[] data = { 1, 2, 3 };
withResetConnection(data, sc -> {
Socket s = sc.socket();
InputStream in = s.getInputStream();
int remaining = data.length;
for (int i=0; i<REPEAT_COUNT; i++) {
try {
int bytesRead = in.read();
if (bytesRead == -1) {
System.out.println("read => EOF");
assertTrue(false);
} else {
System.out.println("read => 1 byte");
assertTrue(remaining > 0);
remaining--;
}
} catch (IOException ioe) {
System.out.format("read => %s%n", ioe);
remaining = 0;
}
int bytesAvailable = in.available();
System.out.format("available => %d%n", bytesAvailable);
assertTrue(bytesAvailable <= remaining);
}
});
}
interface ThrowingConsumer<T> {
void accept(T t) throws IOException;
}
/**
* Invokes a consumer with a SocketChannel connected to a peer that has closed
* the connection with a "connection reset". The peer sends the given data
* bytes before closing (when data is not null).
*/
static void withResetConnection(byte[] data, ThrowingConsumer<SocketChannel> consumer)
throws IOException
{
var loopback = InetAddress.getLoopbackAddress();
try (var listener = new ServerSocket()) {
listener.bind(new InetSocketAddress(loopback, 0));
try (var sc = SocketChannel.open()) {
sc.connect(listener.getLocalSocketAddress());
try (Socket peer = listener.accept()) {
if (data != null) {
peer.getOutputStream().write(data);
}
peer.setSoLinger(true, 0);
}
consumer.accept(sc);
}
}
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2003, 2022, 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.
*/
/**
* @test
* @bug 4915501 6303753
* @summary check exception translation of SocketAdaptor
*/
import java.io.IOException;
import java.nio.channels.*;
import java.net.*;
public class ExceptionTranslation {
public static void main(String args[]) throws Exception {
InetSocketAddress iAddr = new InetSocketAddress("nosuchhostname",5182);
try {
SocketChannel channel = SocketChannel.open();
channel.socket().connect(iAddr, 30000);
throw new RuntimeException("Expected exception not thrown");
} catch (UnknownHostException x) {
// Expected result
}
try {
SocketChannel chan1 = SocketChannel.open();
chan1.socket().bind(new InetSocketAddress(0));
chan1.socket().bind(new InetSocketAddress(0));
throw new RuntimeException("Expected exception not thrown");
} catch(IOException e) {
// Expected result
}
}
}

View file

@ -0,0 +1,160 @@
/*
* Copyright (c) 2001, 2018, 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.
*/
/* @test
* @summary Test SocketChannel.finishConnect
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
* @run main FinishConnect
*/
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.channels.spi.SelectorProvider;
import java.nio.charset.*;
import java.util.*;
public class FinishConnect {
public static void main(String[] args) throws Exception {
try (TestServers.DayTimeServer dayTimeServer
= TestServers.DayTimeServer.startNewServer(100)) {
test1(dayTimeServer, true, true);
test1(dayTimeServer, true, false);
test1(dayTimeServer, false, true);
test1(dayTimeServer, false, false);
test2(dayTimeServer);
}
}
static void test1(TestServers.DayTimeServer daytimeServer,
boolean select,
boolean setBlocking)
throws Exception
{
InetSocketAddress isa
= new InetSocketAddress(daytimeServer.getAddress(),
daytimeServer.getPort());
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
boolean connected = sc.connect(isa);
int attempts = 0;
try {
sc.connect(isa);
throw new RuntimeException("Allowed another connect call");
} catch (IllegalStateException ise) {
// Correct behavior
}
if (setBlocking)
sc.configureBlocking(true);
if (!connected && select && !setBlocking) {
Selector selector = SelectorProvider.provider().openSelector();
sc.register(selector, SelectionKey.OP_CONNECT);
while (!connected) {
int keysAdded = selector.select(100);
if (keysAdded > 0) {
Set readyKeys = selector.selectedKeys();
Iterator i = readyKeys.iterator();
while (i.hasNext()) {
SelectionKey sk = (SelectionKey)i.next();
SocketChannel nextReady =
(SocketChannel)sk.channel();
connected = sc.finishConnect();
}
}
}
selector.close();
}
while (!connected) {
if (attempts++ > 30)
throw new RuntimeException("Failed to connect");
Thread.sleep(100);
connected = sc.finishConnect();
}
ByteBuffer bb = ByteBuffer.allocateDirect(100);
int bytesRead = 0;
int totalRead = 0;
while (totalRead < 20) {
bytesRead = sc.read(bb);
if (bytesRead > 0)
totalRead += bytesRead;
if (bytesRead < 0)
throw new RuntimeException("Message shorter than expected");
}
bb.position(bb.position() - 2); // Drop CRLF
bb.flip();
CharBuffer cb = Charset.forName("US-ASCII").newDecoder().decode(bb);
System.err.println(isa + " says: \"" + cb + "\"");
sc.close();
}
static void test2(TestServers.DayTimeServer daytimeServer) throws Exception {
InetSocketAddress isa
= new InetSocketAddress(daytimeServer.getAddress(),
daytimeServer.getPort());
boolean done = false;
int globalAttempts = 0;
int connectSuccess = 0;
while (!done) {
// When using a local daytime server it is not always possible
// to get a pending connection, as sc.connect(isa) may always
// return true.
// So we're going to throw the exception only if there was
// at least 1 case where we did not manage to connect.
if (globalAttempts++ > 50) {
if (globalAttempts == connectSuccess + 1) {
System.out.println("Can't fully test on "
+ System.getProperty("os.name"));
break;
}
throw new RuntimeException("Failed to connect");
}
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
boolean connected = sc.connect(isa);
int localAttempts = 0;
while (!connected) {
if (localAttempts++ > 500)
throw new RuntimeException("Failed to connect");
connected = sc.finishConnect();
if (connected) {
done = true;
break;
}
Thread.sleep(10);
}
if (connected) {
connectSuccess++;
}
sc.close();
}
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2001, 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.
*/
/* @test
* @bug 4403255
* @summary Tests old streams using channels in socket case
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class GetChannel {
public static void main(String args[]) throws Exception {
InetAddress sin = null;
Socket soc = null,soc1 = null;
InputStream is = null;
OutputStream os = null;
ServerSocket srv = null;
int port = 0;
int tout = 1000;
sin = InetAddress.getLocalHost();
srv = new ServerSocket(port);
port = srv.getLocalPort();
soc = new Socket(sin, port);
soc1 = srv.accept();
BufferedReader bin = new BufferedReader(
new InputStreamReader(soc.getInputStream()));
BufferedWriter bout = new BufferedWriter(
new OutputStreamWriter(soc1.getOutputStream()));
bout.write("hello");
bout.newLine();
bout.flush();
String reply = bin.readLine();
if (!reply.equals("hello"))
throw new RuntimeException("Test failed");
soc.close();
soc1.close();
srv.close();
}
}

View file

@ -0,0 +1,192 @@
/*
* Copyright (c) 2002, 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.
*/
/* @test
* @bug 4617165
* @summary Ensure that socket hangups are handled correctly
* @library ..
* @build TestUtil
* @run main Hangup
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class Hangup {
static PrintStream log = System.err;
static int failures = 0;
private static class Failure
extends RuntimeException
{
Failure(String s) {
super(s);
}
}
static void doSelect(Selector sel, SelectionKey sk, int count)
throws IOException
{
int n = sel.select();
if (n != 1)
throw new Failure("Select returned zero");
Set sks = sel.selectedKeys();
if (sks.size() != 1)
throw new Failure("Wrong size for selected-key set: "
+ sks.size());
if (!sks.remove(sk))
throw new Failure("Key not in selected-key set");
log.println("S: Socket selected #" + count);
}
static void dally() {
try {
Thread.sleep(100);
} catch (InterruptedException x) { }
}
static void test(boolean writeFromClient, boolean readAfterClose)
throws IOException
{
ServerSocketChannel ssc = null;
SocketChannel cl = null; // client end
SocketChannel sv = null; // server end
Selector sel = null;
log.println();
log.println("Test: writeFromClient = " + writeFromClient
+ ", readAfterClose = " + readAfterClose);
try {
int ns = 0; // Number of selection operations done
// Set up server socket
ssc = ServerSocketChannel.open();
SocketAddress sa = TestUtil.bindToRandomPort(ssc);
log.println("S: Listening on port "
+ ssc.socket().getLocalPort());
// Connect client
cl = SocketChannel.open(sa);
log.println("C: Connected via port "
+ cl.socket().getLocalPort());
// Accept client connection
sv = ssc.accept();
log.println("S: Client connection accepted");
// Create selector and register server side
sel = Selector.open();
sv.configureBlocking(false);
SelectionKey sk = sv.register(sel, SelectionKey.OP_READ);
ByteBuffer stuff = ByteBuffer.allocate(10);
int n;
if (writeFromClient) {
// Write from client, read from server
stuff.clear();
if (cl.write(stuff) != stuff.capacity())
throw new Failure("Incorrect number of bytes written");
log.println("C: Wrote stuff");
dally();
doSelect(sel, sk, ++ns);
stuff.clear();
if (sv.read(stuff) != stuff.capacity())
throw new Failure("Wrong number of bytes read");
log.println("S: Read stuff");
}
// Close client side
cl.close();
log.println("C: Socket closed");
dally();
// Select again
doSelect(sel, sk, ++ns);
if (readAfterClose) {
// Read from client after client has disconnected
stuff.clear();
if (sv.read(stuff) != -1)
throw new Failure("Wrong number of bytes read");
log.println("S: Read EOF");
}
// Select a couple more times just to make sure we're doing
// the right thing
doSelect(sel, sk, ++ns);
doSelect(sel, sk, ++ns);
} finally {
if (ssc != null)
ssc.close();
if (cl != null)
cl.close();
if (sv != null)
sv.close();
if (sel != null)
sel.close();
}
}
public static void main(String[] args) throws IOException {
for (boolean writeFromClient = false;; writeFromClient = true) {
for (boolean readAfterClose = false;; readAfterClose = true) {
try {
test(writeFromClient, readAfterClose);
} catch (Failure x) {
x.printStackTrace(log);
failures++;
}
if (readAfterClose)
break;
}
if (writeFromClient)
break;
}
if (failures > 0) {
log.println();
throw new RuntimeException("Some tests failed");
}
}
}

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2018, 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.
*/
/* @test
* @bug 8203059
* @summary Test SocketChannel.close with SO_LINGER enabled
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class LingerOnClose {
private enum TestMode {
BLOCKING,
NON_BLOCKING,
NON_BLOCKING_AND_REGISTERED;
}
public static void main(String[] args) throws IOException {
// blocking mode
test(TestMode.BLOCKING, -1);
test(TestMode.BLOCKING, 0);
test(TestMode.BLOCKING, 1);
// non-blocking mode
test(TestMode.NON_BLOCKING, -1);
test(TestMode.NON_BLOCKING, 0);
test(TestMode.NON_BLOCKING, 1);
// non-blocking mode, close while registered with Selector
test(TestMode.NON_BLOCKING_AND_REGISTERED, -1);
test(TestMode.NON_BLOCKING_AND_REGISTERED, 0);
test(TestMode.NON_BLOCKING_AND_REGISTERED, 1);
}
/**
* Test closing a SocketChannel with SO_LINGER set to the given linger
* interval. If the linger interval is 0, it checks that the peer observes
* a connection reset (TCP RST).
*/
static void test(TestMode mode, int interval) throws IOException {
SocketChannel sc = null;
SocketChannel peer = null;
Selector sel = null;
try (ServerSocketChannel ssc = ServerSocketChannel.open()) {
ssc.bind(new InetSocketAddress(InetAddress.getLocalHost(), 0));
// establish loopback connection
sc = SocketChannel.open(ssc.getLocalAddress());
peer = ssc.accept();
// configured blocking mode and register with Selector if needed
if (mode != TestMode.BLOCKING)
sc.configureBlocking(false);
if (mode == TestMode.NON_BLOCKING_AND_REGISTERED) {
sel = Selector.open();
sc.register(sel, SelectionKey.OP_READ);
sel.selectNow();
}
// enable or disable SO_LINGER
sc.setOption(StandardSocketOptions.SO_LINGER, interval);
// close channel and flush Selector if needed
sc.close();
if (mode == TestMode.NON_BLOCKING_AND_REGISTERED)
sel.selectNow();
// read other end of connection, expect EOF or RST
ByteBuffer bb = ByteBuffer.allocate(100);
try {
int n = peer.read(bb);
if (interval == 0) {
throw new RuntimeException("RST expected");
} else if (n != -1) {
throw new RuntimeException("EOF expected");
}
} catch (IOException ioe) {
if (interval != 0) {
// exception not expected
throw ioe;
}
}
} finally {
if (sc != null) sc.close();
if (peer != null) peer.close();
if (sel != null) sel.close();
}
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2002, 2018, 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.
*/
/* @test
* @bug 4672609 5076965 4739238
* @summary Test getLocalAddress getLocalPort
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
* @run main LocalAddress
*/
import java.net.*;
import java.nio.channels.*;
public class LocalAddress {
public static void main(String[] args) throws Exception {
try (TestServers.EchoServer echoServer
= TestServers.EchoServer.startNewServer()) {
test1(echoServer);
}
}
static void test1(TestServers.AbstractServer server) throws Exception {
InetAddress bogus = InetAddress.getByName("0.0.0.0");
InetSocketAddress saddr = new InetSocketAddress(
server.getAddress(), server.getPort());
//Test1: connect only
SocketChannel sc = SocketChannel.open();
try {
sc.connect(saddr);
InetAddress ia = sc.socket().getLocalAddress();
if (ia == null || ia.equals(bogus))
throw new RuntimeException("test failed");
} finally {
sc.close();
}
//Test2: bind and connect
sc = SocketChannel.open();
try {
sc.socket().bind(new InetSocketAddress(0));
if (sc.socket().getLocalPort() == 0)
throw new RuntimeException("test failed");
sc.socket().connect(saddr);
InetAddress ia = sc.socket().getLocalAddress();
if (ia == null || ia.isAnyLocalAddress())
throw new RuntimeException("test failed");
} finally {
sc.close();
}
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2002, 2017, 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 java.net.SocketException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.Pipe;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
public class Open {
static void test1() {
for (int i=0; i<11000; i++) {
try {
SocketChannel sc = SocketChannel.open();
} catch (Exception e) {
// Presumably "Too many open files"
}
}
}
static void test2() {
for (int i=0; i<11000; i++) {
try {
DatagramChannel sc = DatagramChannel.open();
} catch (Exception e) {
// Presumably "Too many open files"
}
}
}
static void test3() {
SelectorProvider sp = SelectorProvider.provider();
for (int i=0; i<11000; i++) {
try {
Pipe p = sp.openPipe();
} catch (Exception e) {
// Presumably "Too many open files"
}
}
}
static void test4() {
for (int i=0; i<11000; i++) {
try {
ServerSocketChannel sc = ServerSocketChannel.open();
} catch (Exception e) {
// Presumably "Too many open files"
}
}
}
public static void main(String[] args) throws Exception {
// Load necessary classes ahead of time
DatagramChannel dc = DatagramChannel.open();
Exception se = new SocketException();
SelectorProvider sp = SelectorProvider.provider();
Pipe p = sp.openPipe();
ServerSocketChannel ssc = ServerSocketChannel.open();
test1();
test2();
test3();
test4();
}
}

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2007, 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.
*/
/* @test
* @bug 6548464
* @summary SocketChannel.open(SocketAddress) leaks file descriptor if
* connection cannot be established
* @requires vm.flagless
* @build OpenLeak
* @run junit/othervm/timeout=480 OpenLeak
*/
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.channels.SocketChannel;
import java.nio.channels.UnresolvedAddressException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class OpenLeak {
static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ROOT);
static final boolean IS_WINDOWS_2016 = OS_NAME.contains("windows") && OS_NAME.contains("2016");
// On Windows Server 2016 trying to connect to port 47 consumes the
// whole connect timeout - which makes the test fail in timeout.
// We skip this part of the test on Windows Server 2016
static final boolean TEST_WITH_RESERVED_PORT = !IS_WINDOWS_2016;
private static final int MAX_LOOP = 250000;
// Try to find a suitable port to provoke a "Connection Refused"
// error.
private static InetSocketAddress findSuitableRefusedAddress(InetSocketAddress isa)
throws IOException {
if (!TEST_WITH_RESERVED_PORT) return null;
var addr = isa.getAddress();
try (SocketChannel sc1 = SocketChannel.open(isa)) {
// If we manage to connect, let's try to use some other
// port.
// port 51 is reserved too - there should be nothing there...
isa = new InetSocketAddress(addr, 51);
try (SocketChannel sc2 = SocketChannel.open(isa)) {
}
// OK, last attempt...
// port 61 is reserved too - there should be nothing there...
isa = new InetSocketAddress(addr, 61);
try (SocketChannel sc3 = SocketChannel.open(isa)) {
}
System.err.println("Could not find a suitable port");
return null;
} catch (ConnectException x) {
}
return isa;
}
private static InetSocketAddress createUnresolved(InetSocketAddress isa, InetSocketAddress def) {
var sa = isa == null ? def : isa;
return InetSocketAddress.createUnresolved(sa.getHostString(), sa.getPort());
}
// Builds a list of test cases
static List<Object[]> testCases() throws Exception {
InetAddress lo = InetAddress.getLoopbackAddress();
// Try to find a suitable port that will cause a
// Connection Refused exception
// port 47 is reserved - there should be nothing there...
InetSocketAddress def = new InetSocketAddress(lo, 47);
InetSocketAddress isa = findSuitableRefusedAddress(def);
InetSocketAddress sa = createUnresolved(isa, def);
final List<Object[]> cases = new ArrayList<>();
cases.add(new Object[]{sa, UnresolvedAddressException.class});
if (isa != null) {
cases.add(new Object[]{isa, ConnectException.class});
}
return cases;
}
@ParameterizedTest
@MethodSource("testCases")
public void test(SocketAddress sa, Class<? extends Throwable> expectedException) throws Exception {
System.err.printf("%nExpecting %s for %s%n", expectedException, sa);
int i = 0;
try {
for (i = 0; i < MAX_LOOP; i++) {
Throwable x =
assertThrows(expectedException, () -> SocketChannel.open(sa));
if (i < 5 || i >= MAX_LOOP - 5) {
// print a message for the first five and last 5 exceptions
System.err.println(x);
}
}
} catch (Throwable t) {
System.err.println("Failed at " + i + " with " + t);
throw t;
}
}
}

View file

@ -0,0 +1,177 @@
/*
* Copyright (c) 2010, 2015, 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.
*/
/* @test
* @summary Test socket adapter sendUrgentData method
* @bug 6963907
* @key randomness
*/
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.io.IOException;
import java.util.Random;
public class OutOfBand {
private static final Random rand = new Random();
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = null;
SocketChannel sc1 = null;
SocketChannel sc2 = null;
try {
// establish loopback connection
ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
InetAddress lh = InetAddress.getLocalHost();
SocketAddress remote =
new InetSocketAddress(lh, ssc.socket().getLocalPort());
sc1 = SocketChannel.open(remote);
sc2 = ssc.accept();
// enable SO_OOBLINE on server side
sc2.socket().setOOBInline(true);
// run tests
test1(sc1, sc2);
test2(sc1, sc2);
test3(sc1, sc2);
} finally {
if (sc1 != null) sc1.close();
if (sc2 != null) sc2.close();
if (ssc != null) ssc.close();
}
}
/**
* Basic test to check that OOB/TCP urgent byte is received.
*/
static void test1(SocketChannel client, SocketChannel server)
throws Exception
{
assert server.socket().getOOBInline();
ByteBuffer bb = ByteBuffer.allocate(100);
for (int i=0; i<1000; i++) {
int b1 = -127 + rand.nextInt(384);
client.socket().sendUrgentData(b1);
bb.clear();
if (server.read(bb) != 1)
throw new RuntimeException("One byte expected");
bb.flip();
byte b2 = bb.get();
if ((byte)b1 != b2)
throw new RuntimeException("Unexpected byte");
}
}
/**
* Basic test to check that OOB/TCP urgent byte is received, maybe with
* OOB mark changing.
*/
static void test2(final SocketChannel client, SocketChannel server)
throws Exception
{
assert server.socket().getOOBInline();
Runnable sender = new Runnable() {
public void run() {
try {
for (int i=0; i<256; i++)
client.socket().sendUrgentData(i);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
};
Thread thr = new Thread(sender);
thr.start();
ByteBuffer bb = ByteBuffer.allocate(256);
while (bb.hasRemaining()) {
if (server.read(bb) < 0)
throw new RuntimeException("Unexpected EOF");
}
bb.flip();
byte expect = 0;
while (bb.hasRemaining()) {
if (bb.get() != expect)
throw new RuntimeException("Unexpected byte");
expect++;
}
thr.join();
}
/**
* Test that is close to some real world examples where an urgent byte is
* used to "cancel" a long running query or transaction on the server.
*/
static void test3(SocketChannel client, final SocketChannel server)
throws Exception
{
final int STOP = rand.nextInt(256);
assert server.socket().getOOBInline();
Runnable reader = new Runnable() {
public void run() {
ByteBuffer bb = ByteBuffer.allocate(100);
try {
int n = server.read(bb);
if (n != 1) {
String msg = (n < 0) ? "Unexpected EOF" :
"One byte expected";
throw new RuntimeException(msg);
}
bb.flip();
if (bb.get() != (byte)STOP)
throw new RuntimeException("Unexpected byte");
bb.flip();
server.write(bb);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
};
Thread thr = new Thread(reader);
thr.start();
// "stop" server
client.socket().sendUrgentData(STOP);
// wait for server reply
ByteBuffer bb = ByteBuffer.allocate(100);
int n = client.read(bb);
if (n != 1)
throw new RuntimeException("Unexpected number of bytes");
bb.flip();
if (bb.get() != (byte)STOP)
throw new RuntimeException("Unexpected reply");
thr.join();
}
}

View file

@ -0,0 +1,195 @@
/*
* Copyright (c) 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.
*/
/*
* @test
* @bug 8358764
* @summary Test closing a socket while a thread is blocked in read. The connection
* should be closed gracefuly so that the peer reads EOF.
* @run junit PeerReadsAfterAsyncClose
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.*;
class PeerReadsAfterAsyncClose {
static Stream<ThreadFactory> factories() {
return Stream.of(Thread.ofPlatform().factory(), Thread.ofVirtual().factory());
}
/**
* Close SocketChannel while a thread is blocked reading from the channel's socket.
*/
@ParameterizedTest
@MethodSource("factories")
void testCloseDuringSocketChannelRead(ThreadFactory factory) throws Exception {
var loopback = InetAddress.getLoopbackAddress();
try (var listener = new ServerSocket()) {
listener.bind(new InetSocketAddress(loopback, 0));
try (SocketChannel sc = SocketChannel.open(listener.getLocalSocketAddress());
Socket peer = listener.accept()) {
// start thread to read from channel
var cceThrown = new AtomicBoolean();
Thread thread = factory.newThread(() -> {
try {
sc.read(ByteBuffer.allocate(1));
fail();
} catch (ClosedChannelException e) {
cceThrown.set(true);
} catch (Throwable e) {
e.printStackTrace();
}
});
thread.start();
try {
// close SocketChannel when thread sampled in implRead
onReach(thread, "sun.nio.ch.SocketChannelImpl.implRead", () -> {
try {
sc.close();
} catch (IOException ignore) { }
});
// peer should read EOF
int n = peer.getInputStream().read();
assertEquals(-1, n);
} finally {
thread.join();
}
assertEquals(true, cceThrown.get(), "ClosedChannelException not thrown");
}
}
}
/**
* Close Socket while a thread is blocked reading from the socket.
*/
@ParameterizedTest
@MethodSource("factories")
void testCloseDuringSocketUntimedRead(ThreadFactory factory) throws Exception {
testCloseDuringSocketRead(factory, 0);
}
/**
* Close Socket while a thread is blocked reading from the socket with a timeout.
*/
@ParameterizedTest
@MethodSource("factories")
void testCloseDuringSockeTimedRead(ThreadFactory factory) throws Exception {
testCloseDuringSocketRead(factory, 60_000);
}
private void testCloseDuringSocketRead(ThreadFactory factory, int timeout) throws Exception {
var loopback = InetAddress.getLoopbackAddress();
try (var listener = new ServerSocket()) {
listener.bind(new InetSocketAddress(loopback, 0));
try (Socket s = new Socket(loopback, listener.getLocalPort());
Socket peer = listener.accept()) {
// start thread to read from socket
var seThrown = new AtomicBoolean();
Thread thread = factory.newThread(() -> {
try {
s.setSoTimeout(timeout);
s.getInputStream().read();
fail();
} catch (SocketException e) {
seThrown.set(true);
} catch (Throwable e) {
e.printStackTrace();
}
});
thread.start();
try {
// close Socket when thread sampled in implRead
onReach(thread, "sun.nio.ch.NioSocketImpl.implRead", () -> {
try {
s.close();
} catch (IOException ignore) { }
});
// peer should read EOF
int n = peer.getInputStream().read();
assertEquals(-1, n);
} finally {
thread.join();
}
assertEquals(true, seThrown.get(), "SocketException not thrown");
}
}
}
/**
* Runs the given action when the given target thread is sampled at the given
* location. The location takes the form "{@code c.m}" where
* {@code c} is the fully qualified class name and {@code m} is the method name.
*/
private void onReach(Thread target, String location, Runnable action) {
int index = location.lastIndexOf('.');
String className = location.substring(0, index);
String methodName = location.substring(index + 1);
Thread.ofPlatform().daemon(true).start(() -> {
try {
boolean found = false;
while (!found) {
found = contains(target.getStackTrace(), className, methodName);
if (!found) {
Thread.sleep(20);
}
}
action.run();
} catch (Exception e) {
e.printStackTrace();
}
});
}
/**
* Returns true if the given stack trace contains an element for the given class
* and method name.
*/
private boolean contains(StackTraceElement[] stack, String className, String methodName) {
return Arrays.stream(stack)
.anyMatch(e -> className.equals(e.getClassName())
&& methodName.equals(e.getMethodName()));
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2020, 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 org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import static org.testng.Assert.*;
/*
* @test
* @bug 8246707
* @library /test/lib
* @summary Reading or Writing to a closed SocketChannel should throw a ClosedChannelException
* @run testng/othervm ReadWriteAfterClose
*/
public class ReadWriteAfterClose {
private ServerSocketChannel listener;
private SocketAddress saddr;
private static final int bufCapacity = 4;
private static final int bufArraySize = 4;
private static final Class<ClosedChannelException> CCE = ClosedChannelException.class;
@BeforeTest
public void setUp() throws IOException {
listener = ServerSocketChannel.open();
listener.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
saddr = listener.getLocalAddress();
}
@Test
public void testWriteAfterClose1() throws IOException {
SocketChannel sc = SocketChannel.open(saddr);
sc.close();
ByteBuffer bufWrite = ByteBuffer.allocate(bufCapacity);
Throwable ex = expectThrows(CCE, () -> sc.write(bufWrite));
assertEquals(ex.getClass(), CCE);
}
@Test
public void testWriteAfterClose2() throws IOException {
SocketChannel sc = SocketChannel.open(saddr);
sc.close();
ByteBuffer[] bufArrayWrite = allocateBufArray();
Throwable ex = expectThrows(CCE, () -> sc.write(bufArrayWrite));
assertEquals(ex.getClass(), CCE);
}
@Test
public void testWriteAfterClose3() throws IOException {
SocketChannel sc = SocketChannel.open(saddr);
sc.close();
ByteBuffer[] bufArrayWrite = allocateBufArray();
Throwable ex = expectThrows(CCE, () -> sc.write(bufArrayWrite, 0, bufArraySize));
assertEquals(ex.getClass(), CCE);
}
@Test
public void testReadAfterClose1() throws IOException {
SocketChannel sc = SocketChannel.open(saddr);
sc.close();
ByteBuffer dst = ByteBuffer.allocate(bufCapacity);
Throwable ex = expectThrows(CCE, () -> sc.read(dst));
assertEquals(ex.getClass(), CCE);
}
@Test
public void testReadAfterClose2() throws IOException {
SocketChannel sc = SocketChannel.open(saddr);
sc.close();
ByteBuffer[] dstArray = allocateBufArray();
Throwable ex = expectThrows(CCE, () -> sc.read(dstArray));
assertEquals(ex.getClass(), CCE);
}
@Test
public void testReadAfterClose3() throws IOException {
SocketChannel sc = SocketChannel.open(saddr);
sc.close();
ByteBuffer[] dstArray = allocateBufArray();
Throwable ex = expectThrows(CCE, () -> sc.read(dstArray, 0, bufArraySize));
assertEquals(ex.getClass(), CCE);
}
public ByteBuffer[] allocateBufArray() {
ByteBuffer[] bufArr = new ByteBuffer[bufArraySize];
for (int i = 0; i < bufArraySize; i++)
bufArr[i] = ByteBuffer.allocate(bufCapacity);
return bufArr;
}
@AfterTest
public void tearDown() throws IOException {
listener.close();
}
}

View file

@ -0,0 +1,205 @@
/*
* Copyright (c) 2015, 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
* 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.
*/
/* @test
* @bug 8071599
* @run main/othervm SendUrgentData
* @run main/othervm SendUrgentData -inline
* @summary Test sending of urgent data.
*/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class SendUrgentData {
/**
* The arguments may be one of the following:
* <ol>
* <li>-server</li>
* <li>-client host port [-inline]</li>
* <li>[-inline]</li>
* </ol>
* The first option creates a standalone server, the second a standalone
* client, and the third a self-contained server-client pair on the
* local host.
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ServerSocketChannelThread serverThread
= new ServerSocketChannelThread("SendUrgentDataServer");
serverThread.start();
boolean b = serverThread.isAlive();
String host = null;
int port = 0;
boolean inline = false;
if (args.length > 0 && args[0].equals("-server")) {
System.out.println(serverThread.getAddress());
while (true) {
Thread.sleep(60_000);
}
} else {
if (args.length > 0 && args[0].equals("-client")) {
host = args[1];
port = Integer.parseInt(args[2]);
if (args.length > 3) {
inline = args[2].equals("-inline");
}
} else {
host = "localhost";
port = serverThread.getAddress().getPort();
if (args.length > 0) {
inline = args[0].equals("-inline");
}
}
}
System.out.println("OOB Inline : "+inline);
SocketAddress sa = new InetSocketAddress(host, port);
try (SocketChannel sc = SocketChannel.open(sa)) {
sc.configureBlocking(false);
sc.socket().setOOBInline(inline);
sc.socket().sendUrgentData(0);
System.out.println("wrote 1 OOB byte");
ByteBuffer bb = ByteBuffer.wrap(new byte[100 * 1000]);
int blocked = 0;
long total = 0;
int n;
do {
n = sc.write(bb);
if (n == 0) {
System.out.println("blocked, wrote " + total + " so far");
if (++blocked == 10) {
break;
}
Thread.sleep(100);
} else {
total += n;
bb.rewind();
}
} while (n > 0);
long attempted = 0;
while (attempted < total) {
bb.rewind();
n = sc.write(bb);
System.out.println("wrote " + n + " normal bytes");
attempted += bb.capacity();
String osName = System.getProperty("os.name").toLowerCase();
try {
sc.socket().sendUrgentData(0);
} catch (IOException ex) {
if (osName.contains("linux")) {
if (!ex.getMessage().contains("Socket buffer full")) {
throw new RuntimeException("Unexpected message", ex);
}
} else if (osName.contains("os x") || osName.contains("mac")) {
if (!ex.getMessage().equals("No buffer space available")) {
throw new RuntimeException("Unexpected message", ex);
}
} else if (osName.contains("windows")) {
if (!ex.getMessage().equals("Socket buffer full")) {
throw new RuntimeException("Unexpected message", ex);
}
} else {
throw new RuntimeException("Unexpected IOException", ex);
}
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
// don't want to fail on this so just print trace and break
ex.printStackTrace();
break;
}
}
} finally {
serverThread.close();
}
}
static class ServerSocketChannelThread extends Thread {
private ServerSocketChannel ssc;
private ServerSocketChannelThread(String name) {
super(name);
try {
ssc = ServerSocketChannel.open();
ssc.bind(new InetSocketAddress((0)));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
public void run() {
while (ssc.isOpen()) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
try {
ssc.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
System.out.println("ServerSocketChannelThread exiting ...");
}
public InetSocketAddress getAddress() throws IOException {
if (ssc == null) {
throw new IllegalStateException("ServerSocketChannel not created");
}
return (InetSocketAddress) ssc.getLocalAddress();
}
public void close() {
try {
ssc.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
}

View file

@ -0,0 +1,210 @@
/*
* Copyright (c) 2012, 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.
*/
/* @test
* @bug 7176630 7074436
* @summary Check for short writes on SocketChannels configured in blocking mode
* @key randomness
* @requires test.thread.factory != "Virtual"
*/
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.concurrent.*;
import java.util.Random;
import java.util.zip.CRC32;
public class ShortWrite {
static final Random rand = new Random();
/**
* Returns a checksum on the remaining bytes in the given buffers.
*/
static long computeChecksum(ByteBuffer... bufs) {
CRC32 crc32 = new CRC32();
for (int i=0; i<bufs.length; i++)
crc32.update(bufs[i]);
return crc32.getValue();
}
/**
* A task that reads the expected number of bytes and returns the CRC32
* of those bytes.
*/
static class Reader implements Callable<Long> {
final SocketChannel sc;
final ByteBuffer buf;
Reader(SocketChannel sc, int expectedSize) {
this.sc = sc;
this.buf = ByteBuffer.allocate(expectedSize);
}
public Long call() throws Exception {
while (buf.hasRemaining()) {
int n = sc.read(buf);
if (n == -1)
throw new RuntimeException("Premature EOF encountered");
}
buf.flip();
return computeChecksum(buf);
}
}
/**
* Exercise write(ByteBuffer) with given number of bytes.
*/
static void test1(ExecutorService pool,
SocketChannel source,
SocketChannel sink,
int size)
throws Exception
{
System.out.println("write(ByteBuffer), size=" + size);
// random bytes in the buffer
ByteBuffer buf = ByteBuffer.allocate(size);
rand.nextBytes(buf.array());
// submit task to read the bytes
Future<Long> result = pool.submit(new Reader(sink, size));
// write the bytes
int n = source.write(buf);
if (n != size)
throw new RuntimeException("Short write detected");
// check the bytes that were received match
buf.rewind();
long expected = computeChecksum(buf);
long actual = result.get();
if (actual != expected)
throw new RuntimeException("Checksum did not match");
}
/**
* Exercise write(ByteBuffer[]) with buffers of the given sizes.
*/
static void testN(ExecutorService pool,
SocketChannel source,
SocketChannel sink,
int... sizes)
throws Exception
{
System.out.print("write(ByteBuffer[]), sizes=");
for (int size: sizes)
System.out.print(size + " ");
System.out.println();
int total = 0;
int len = sizes.length;
ByteBuffer[] bufs = new ByteBuffer[len];
for (int i=0; i<len; i++) {
int size = sizes[i];
ByteBuffer buf = ByteBuffer.allocate(size);
rand.nextBytes(buf.array());
bufs[i] = buf;
total += size;
}
// submit task to read the bytes
Future<Long> result = pool.submit(new Reader(sink, total));
// write the bytes
long n = source.write(bufs);
if (n != total)
throw new RuntimeException("Short write detected");
// check the bytes that were received match
for (int i=0; i<len; i++)
bufs[i].rewind();
long expected = computeChecksum(bufs);
long actual = result.get();
if (actual != expected)
throw new RuntimeException("Checksum did not match");
}
public static void main(String[] args) throws Exception {
ExecutorService pool = Executors.newSingleThreadExecutor();
try {
try (ServerSocketChannel ssc = ServerSocketChannel.open()) {
ssc.bind(new InetSocketAddress(0));
InetAddress lh = InetAddress.getLocalHost();
int port = ssc.socket().getLocalPort();
SocketAddress sa = new InetSocketAddress(lh, port);
try (SocketChannel source = SocketChannel.open(sa);
SocketChannel sink = ssc.accept())
{
// Exercise write(BufferBuffer) on sizes around 128k
int BOUNDARY = 128 * 1024;
for (int size=(BOUNDARY-2); size<=(BOUNDARY+2); size++) {
test1(pool, source, sink, size);
}
// Exercise write(BufferBuffer) on random sizes
for (int i=0; i<20; i++) {
int size = rand.nextInt(1024*1024);
test1(pool, source, sink, size);
}
// Exercise write(BufferBuffer[]) on sizes around 128k
for (int i=BOUNDARY-2; i<=BOUNDARY+2; i++) {
testN(pool, source, sink, i);
testN(pool, source, sink, 0, i);
testN(pool, source, sink, i, 0);
for (int j=BOUNDARY-2; j<=BOUNDARY+2; j++) {
testN(pool, source, sink, i, j);
testN(pool, source, sink, 0, i, j);
testN(pool, source, sink, i, 0, j);
testN(pool, source, sink, i, j, 0);
for (int k=BOUNDARY-2; k<=BOUNDARY+2; k++) {
testN(pool, source, sink, i, j, k);
testN(pool, source, sink, 0, i, j, k);
testN(pool, source, sink, i, 0, j, k);
testN(pool, source, sink, i, j, 0, k);
testN(pool, source, sink, i, j, k, 0);
}
}
}
// Exercise write(BufferBuffer[]) on random sizes
// (assumes IOV_MAX >= 8)
for (int i=0; i<20; i++) {
int n = rand.nextInt(9);
int[] sizes = new int[n];
for (int j=0; j<n; j++) {
sizes[j] = rand.nextInt(1024*1024);
}
testN(pool, source, sink, sizes);
}
}
}
} finally {
pool.shutdown();
}
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2002, 2011, 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.
*/
/* @test
* @bug 4618960 4516760
* @summary Test shutdownXXX and isInputShutdown
*/
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
public class Shutdown {
/**
* Accept a connection, and close it immediately causing a hard reset.
*/
static void acceptAndReset(ServerSocketChannel ssc) throws IOException {
SocketChannel peer = ssc.accept();
try {
peer.setOption(StandardSocketOptions.SO_LINGER, 0);
peer.configureBlocking(false);
peer.write(ByteBuffer.wrap(new byte[128*1024]));
} finally {
peer.close();
}
}
public static void main(String[] args) throws Exception {
ServerSocketChannel ssc = ServerSocketChannel.open()
.bind(new InetSocketAddress(0));
try {
InetAddress lh = InetAddress.getLocalHost();
int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort();
SocketAddress remote = new InetSocketAddress(lh, port);
// Test SocketChannel shutdownXXX
SocketChannel sc;
sc = SocketChannel.open(remote);
try {
acceptAndReset(ssc);
sc.shutdownInput();
sc.shutdownOutput();
} finally {
sc.close();
}
// Test Socket adapter shutdownXXX and isShutdownInput
sc = SocketChannel.open(remote);
try {
acceptAndReset(ssc);
boolean before = sc.socket().isInputShutdown();
sc.socket().shutdownInput();
boolean after = sc.socket().isInputShutdown();
if (before || !after)
throw new RuntimeException("Before and after test failed");
sc.socket().shutdownOutput();
} finally {
sc.close();
}
} finally {
ssc.close();
}
}
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2007, 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.
*/
/*
* @test
* @summary Sockets shouldn't be inherited when creating a child process
* @requires (os.family == "windows")
*/
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.net.*;
import java.io.*;
public class SocketInheritance {
/*
* Simple helper class to direct process output to the parent
* System.out
*/
static class IOHandler implements Runnable {
InputStream in;
IOHandler(InputStream in) {
this.in = in;
}
static void handle(InputStream in) {
IOHandler handler = new IOHandler(in);
Thread thr = new Thread(handler);
thr.setDaemon(true);
thr.start();
}
public void run() {
try {
byte b[] = new byte[100];
for (;;) {
int n = in.read(b);
if (n < 0) return;
System.out.write(b, 0, n);
}
} catch (IOException ioe) { }
}
}
// connect to the given port
static SocketChannel connect(int port) throws IOException {
InetAddress lh = InetAddress.getLoopbackAddress();
InetSocketAddress isa = new InetSocketAddress(lh, port);
return SocketChannel.open(isa);
}
// simple child process that handshakes with the parent and then
// waits indefinitely until it is destroyed
static void child(int port) {
try {
connect(port).close();
} catch (IOException x) {
x.printStackTrace();
return;
}
for (;;) {
try {
Thread.sleep(10*1000);
} catch (InterruptedException x) { }
}
}
// Creates a loopback connection.
// Forks process which should not inherit the sockets.
// Close the sockets, and attempt to re-bind the listener.
static void start() throws Exception {
// setup loopback connection
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind( new InetSocketAddress(0) );
int port = ssc.socket().getLocalPort();
SocketChannel sc1 = connect(port);
SocketChannel sc2 = ssc.accept();
// launch the child
String cmd = System.getProperty("java.home") + File.separator + "bin" +
File.separator + "java";
String testClasses = System.getProperty("test.classes");
if (testClasses != null)
cmd += " -cp " + testClasses;
cmd += " SocketInheritance -child " + port;
Process p = Runtime.getRuntime().exec(cmd);
IOHandler.handle(p.getInputStream());
IOHandler.handle(p.getErrorStream());
// wait for child to connect
SocketChannel sc3 = ssc.accept();
// close sockets
sc1.close();
sc2.close();
sc3.close();
ssc.close();
// re-bind the listener - if the sockets were inherited then
// this will fail
try {
ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(port));
ssc.close();
} finally {
p.destroy();
}
}
public static void main(String[] args) throws Exception {
if (args.length == 0) {
start();
} else {
if (args[0].equals("-child")) {
child(Integer.parseInt(args[1]));
}
}
}
}

View file

@ -0,0 +1,165 @@
/*
* Copyright (c) 2007, 2019, 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.
*/
/* @test
* @bug 4640544 8044773
* @summary Unit test to check SocketChannel setOption/getOption/options
* methods.
* @modules java.base/sun.net.ext
* jdk.net
* @requires !vm.graal.enabled
* @run main SocketOptionTests
* @run main/othervm --limit-modules=java.base SocketOptionTests
*/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketOption;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;
import java.util.Set;
import sun.net.ext.ExtendedSocketOptions;
import static java.net.StandardSocketOptions.*;
import static jdk.net.ExtendedSocketOptions.*;
public class SocketOptionTests {
static void checkOption(SocketChannel sc, SocketOption name, Object expectedValue)
throws IOException
{
Object value = sc.getOption(name);
if (!value.equals(expectedValue))
throw new RuntimeException("value not as expected");
}
public static void main(String[] args) throws IOException {
try (var channel = SocketChannel.open()) {
test(channel);
}
}
static void test(SocketChannel sc) throws IOException {
Set<SocketOption<?>> extendedOptions = ExtendedSocketOptions.clientSocketOptions();
Set<SocketOption<?>> keepAliveOptions = Set.of(TCP_KEEPCOUNT, TCP_KEEPIDLE, TCP_KEEPINTERVAL);
boolean keepAliveOptionsSupported = extendedOptions.containsAll(keepAliveOptions);
Set<SocketOption<?>> expected;
if (keepAliveOptionsSupported) {
expected = Set.of(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
SO_REUSEADDR, SO_LINGER, TCP_NODELAY, TCP_KEEPCOUNT,
TCP_KEEPIDLE, TCP_KEEPINTERVAL);
} else {
expected = Set.of(SO_SNDBUF, SO_RCVBUF, SO_KEEPALIVE,
SO_REUSEADDR, SO_LINGER, TCP_NODELAY);
}
for (SocketOption opt: expected) {
if (!sc.supportedOptions().contains(opt))
throw new RuntimeException(opt.name() + " should be supported");
}
// check specified defaults
int linger = sc.<Integer>getOption(SO_LINGER);
if (linger >= 0)
throw new RuntimeException("initial value of SO_LINGER should be < 0");
checkOption(sc, SO_KEEPALIVE, false);
checkOption(sc, TCP_NODELAY, false);
// allowed to change when not bound
sc.setOption(SO_KEEPALIVE, true);
checkOption(sc, SO_KEEPALIVE, true);
sc.setOption(SO_KEEPALIVE, false);
checkOption(sc, SO_KEEPALIVE, false);
sc.setOption(SO_SNDBUF, 128*1024); // can't check
sc.setOption(SO_RCVBUF, 256*1024); // can't check
int before, after;
before = sc.getOption(SO_SNDBUF);
after = sc.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
if (after < before)
throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
before = sc.getOption(SO_RCVBUF);
after = sc.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
if (after < before)
throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
sc.setOption(SO_REUSEADDR, true);
checkOption(sc, SO_REUSEADDR, true);
sc.setOption(SO_REUSEADDR, false);
checkOption(sc, SO_REUSEADDR, false);
sc.setOption(SO_LINGER, 10);
linger = sc.<Integer>getOption(SO_LINGER);
if (linger < 1)
throw new RuntimeException("expected linger to be enabled");
sc.setOption(SO_LINGER, -1);
linger = sc.<Integer>getOption(SO_LINGER);
if (linger >= 0)
throw new RuntimeException("expected linger to be disabled");
sc.setOption(TCP_NODELAY, true);
checkOption(sc, TCP_NODELAY, true);
sc.setOption(TCP_NODELAY, false); // can't check
// bind socket
sc.bind(new InetSocketAddress(0));
// allow to change when bound
sc.setOption(SO_KEEPALIVE, true);
checkOption(sc, SO_KEEPALIVE, true);
sc.setOption(SO_KEEPALIVE, false);
checkOption(sc, SO_KEEPALIVE, false);
sc.setOption(SO_LINGER, 10);
linger = sc.<Integer>getOption(SO_LINGER);
if (linger < 1)
throw new RuntimeException("expected linger to be enabled");
sc.setOption(SO_LINGER, -1);
linger = sc.<Integer>getOption(SO_LINGER);
if (linger >= 0)
throw new RuntimeException("expected linger to be disabled");
sc.setOption(TCP_NODELAY, true); // can't check
sc.setOption(TCP_NODELAY, false); // can't check
if (keepAliveOptionsSupported) {
sc.setOption(TCP_KEEPIDLE, 1234);
checkOption(sc, TCP_KEEPIDLE, 1234);
sc.setOption(TCP_KEEPINTERVAL, 123);
checkOption(sc, TCP_KEEPINTERVAL, 123);
sc.setOption(TCP_KEEPCOUNT, 7);
checkOption(sc, TCP_KEEPCOUNT, 7);
}
// NullPointerException
try {
sc.setOption(null, "value");
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException x) {
}
try {
sc.getOption(null);
throw new RuntimeException("NullPointerException not thrown");
} catch (NullPointerException x) {
}
// ClosedChannelException
sc.close();
try {
sc.setOption(TCP_NODELAY, true);
throw new RuntimeException("ClosedChannelException not thrown");
} catch (ClosedChannelException x) {
}
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2001, 2010, 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.
*/
/* @test
* @summary Test trivial stuff
*/
import java.nio.channels.*;
public class Trivial {
public static void main(String[] args) throws Exception {
SocketChannel sc = SocketChannel.open();
Selector sel = Selector.open();
try {
if (sc.keyFor(sel) != null)
throw new Exception("keyFor != null");
sc.configureBlocking(false);
SelectionKey sk = sc.register(sel, SelectionKey.OP_READ, args);
if (sc.keyFor(sel) != sk)
throw new Exception("keyFor returned " + sc.keyFor(sel));
if (sk.attachment() != args)
throw new Exception("attachment() returned " + sk.attachment());
Trivial t = new Trivial();
sk.attach(t);
if (sk.attachment() != t)
throw new Exception("Wrong attachment");
sk.isReadable();
sk.isWritable();
sk.isConnectable();
sk.isAcceptable();
} finally {
sel.close();
sc.close();
}
}
}

View file

@ -0,0 +1,107 @@
/*
* Copyright (c) 2006, 2010, 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.
*/
/* @test
* @bug 6442073
* @summary Check getXXX methods for local/remote port/address/socketaddress
* match socket spec for unbound case
*/
import java.net.*;
import java.nio.channels.*;
public class UnboundSocketTests {
static int failures = 0;
static void check(String msg, Object actual, Object expected) {
System.out.format("%s expected: %s, actual: %s", msg, expected, actual);
if (actual == expected) {
System.out.println(" [PASS]");
} else {
System.out.println(" [FAIL]");
failures++;
}
}
static void checkIsAnyLocalAddress(String msg, InetAddress actual) {
System.out.format("%s actual: %s", msg, actual);
if (actual.isAnyLocalAddress()) {
System.out.println(" [PASS]");
} else {
System.out.println(" [FAIL]");
failures++;
}
}
public static void main(String[] args) throws Exception {
System.out.println("\n-- SocketChannel --");
SocketChannel sc = SocketChannel.open();
try {
check("getLocalPort()", sc.socket().getLocalPort(), -1);
checkIsAnyLocalAddress("getLocalAddress()",
sc.socket().getLocalAddress());
check("getLocalSocketAddress()", sc.socket().getLocalSocketAddress(), null);
check("getPort()", sc.socket().getPort(), 0);
check("getInetAddress()", sc.socket().getInetAddress(), null);
check("getRemoteSocketAddress()", sc.socket().getRemoteSocketAddress(), null);
} finally {
sc.close();
}
System.out.println("\n-- ServerSocketChannel --");
ServerSocketChannel ssc = ServerSocketChannel.open();
try {
check("getLocalPort()", ssc.socket().getLocalPort(), -1);
check("getInetAddress()", ssc.socket().getInetAddress(), null);
check("getLocalSocketAddress()", ssc.socket().getLocalSocketAddress(), null);
} finally {
ssc.close();
}
System.out.println("\n-- DatagramChannel --");
DatagramChannel dc = DatagramChannel.open();
try {
// not specified
check("getLocalPort()", dc.socket().getLocalPort(), 0);
checkIsAnyLocalAddress("getLocalAddress()",
dc.socket().getLocalAddress());
check("getLocalSocketAddress()", dc.socket().getLocalSocketAddress(), null);
check("getPort()", dc.socket().getPort(), -1);
check("getInetAddress()", dc.socket().getInetAddress(), null);
check("getRemoteSocketAddress()", dc.socket().getRemoteSocketAddress(), null);
} finally {
dc.close();
}
if (failures > 0) {
throw new RuntimeException(failures + " sub-tests(s) failed.");
}
}
}

View file

@ -0,0 +1,221 @@
/*
* Copyright (c) 2000, 2017, 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.
*/
/* @test
* @bug 8191025
* @summary Test socketchannel vector IO (use -Dseed=X to set PRNG seed)
* @library .. /test/lib
* @build jdk.test.lib.RandomFactory
* @run main VectorIO
* @key randomness
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
import jdk.test.lib.RandomFactory;
public class VectorIO {
private static Random generator = RandomFactory.getRandom();
static int testSize;
// whether to use the write/read variant with a length parameter
static boolean setLength;
public static void main(String[] args) throws Exception {
testSize = 1;
setLength = false;
runTest();
for(int i=15; i<18; i++) {
testSize = i;
setLength = !setLength;
runTest();
}
}
static void runTest() throws Exception {
System.err.println("Length " + testSize);
Server sv = new Server(testSize);
sv.start();
bufferTest(sv.port());
if (sv.finish(8000) == 0)
throw new Exception("Failed: Length = " + testSize);
}
static void bufferTest(int port) throws Exception {
ByteBuffer[] bufs = new ByteBuffer[testSize];
long total = 0L;
for(int i=0; i<testSize; i++) {
String source = "buffer" + i;
if (generator.nextBoolean())
bufs[i] = ByteBuffer.allocateDirect(source.length());
else
bufs[i] = ByteBuffer.allocate(source.length());
bufs[i].put(source.getBytes("8859_1"));
bufs[i].flip();
total += bufs[i].remaining();
}
ByteBuffer[] bufsPlus1 = new ByteBuffer[bufs.length + 1];
System.arraycopy(bufs, 0, bufsPlus1, 0, bufs.length);
// Get a connection to the server
InetAddress lh = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(lh, port);
SocketChannel sc = SocketChannel.open();
sc.connect(isa);
sc.configureBlocking(generator.nextBoolean());
// Write the data out
long rem = total;
while (rem > 0L) {
long bytesWritten;
if (setLength) {
bytesWritten = sc.write(bufsPlus1, 0, bufs.length);
} else {
bytesWritten = sc.write(bufs);
}
if (bytesWritten == 0) {
if (sc.isBlocking()) {
throw new RuntimeException("write did not block");
} else {
System.err.println("Non-blocking write() wrote zero bytes");
}
Thread.sleep(50);
} else {
rem -= bytesWritten;
}
}
// Clean up
sc.close();
}
static class Server
extends TestThread
{
final int testSize;
final ServerSocketChannel ssc;
Server(int testSize) throws IOException {
super("Server " + testSize);
this.testSize = testSize;
this.ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
}
int port() {
return ssc.socket().getLocalPort();
}
void go() throws Exception {
bufferTest();
}
void bufferTest() throws Exception {
long total = 0L;
ByteBuffer[] bufs = new ByteBuffer[testSize];
for(int i=0; i<testSize; i++) {
String source = "buffer" + i;
if (generator.nextBoolean())
bufs[i] = ByteBuffer.allocateDirect(source.length());
else
bufs[i] = ByteBuffer.allocate(source.length());
total += bufs[i].capacity();
}
ByteBuffer[] bufsPlus1 = new ByteBuffer[bufs.length + 1];
System.arraycopy(bufs, 0, bufsPlus1, 0, bufs.length);
// Get a connection from client
SocketChannel sc = null;
try {
ssc.configureBlocking(false);
for (;;) {
sc = ssc.accept();
if (sc != null) {
System.err.println("accept() succeeded");
break;
}
Thread.sleep(50);
}
sc.configureBlocking(generator.nextBoolean());
// Read data into multiple buffers
long avail = total;
while (avail > 0) {
long bytesRead;
if (setLength) {
bytesRead = sc.read(bufsPlus1, 0, bufs.length);
} else {
bytesRead = sc.read(bufs);
}
if (bytesRead < 0)
break;
if (bytesRead == 0) {
if (sc.isBlocking()) {
throw new RuntimeException("read did not block");
} else {
System.err.println
("Non-blocking read() read zero bytes");
}
Thread.sleep(50);
}
avail -= bytesRead;
}
// Check results
for(int i=0; i<testSize; i++) {
String expected = "buffer" + i;
bufs[i].flip();
int size = bufs[i].capacity();
byte[] data = new byte[size];
for(int j=0; j<size; j++)
data[j] = bufs[i].get();
String message = new String(data, "8859_1");
if (!message.equals(expected))
throw new Exception("Wrong data: Got "
+ message + ", expected "
+ expected);
}
} finally {
// Clean up
ssc.close();
if (sc != null)
sc.close();
}
}
}
}

View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2003, 2018, 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.
*/
/* @test
* @bug 4865031
* @summary Test ScatteringByteChannel/GatheringByteChannel read/write
* @library .. /test/lib
* @build jdk.test.lib.Utils TestServers
* @run main VectorParams
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class VectorParams {
static java.io.PrintStream out = System.out;
static final int testSize = 10;
static ByteBuffer[] bufs = null;
static InetSocketAddress isa = null;
public static void main(String[] args) throws Exception {
try (TestServers.DayTimeServer daytimeServer
= TestServers.DayTimeServer.startNewServer(100)) {
initBufs(daytimeServer);
testSocketChannelVectorParams();
testDatagramChannelVectorParams();
testPipeVectorParams();
testFileVectorParams();
}
}
static void initBufs(TestServers.DayTimeServer daytimeServer) throws Exception {
bufs = new ByteBuffer[testSize];
for(int i=0; i<testSize; i++) {
String source = "buffer" + i;
bufs[i] = ByteBuffer.allocate(source.length());
bufs[i].put(source.getBytes("8859_1"));
bufs[i].flip();
}
isa = new InetSocketAddress(daytimeServer.getAddress(),
daytimeServer.getPort());
}
static void testSocketChannelVectorParams() throws Exception {
SocketChannel sc = SocketChannel.open(isa);
tryBadWrite(sc, bufs, 0, -1);
tryBadWrite(sc, bufs, -1, 0);
tryBadWrite(sc, bufs, 0, 1000);
tryBadWrite(sc, bufs, 1000, 1);
tryBadRead(sc, bufs, 0, -1);
tryBadRead(sc, bufs, -1, 0);
tryBadRead(sc, bufs, 0, 1000);
tryBadRead(sc, bufs, 1000, 1);
sc.close();
}
static void testDatagramChannelVectorParams() throws Exception {
DatagramChannel dc = DatagramChannel.open();
dc.connect(isa);
tryBadRead(dc, bufs, 0, -1);
tryBadRead(dc, bufs, -1, 0);
tryBadRead(dc, bufs, 0, 1000);
tryBadRead(dc, bufs, 1000, 1);
tryBadWrite(dc, bufs, 0, -1);
tryBadWrite(dc, bufs, -1, 0);
tryBadWrite(dc, bufs, 0, 1000);
tryBadWrite(dc, bufs, 1000, 1);
dc.close();
}
static void testPipeVectorParams() throws Exception {
Pipe p = Pipe.open();
Pipe.SinkChannel sink = p.sink();
Pipe.SourceChannel source = p.source();
tryBadWrite(sink, bufs, 0, -1);
tryBadWrite(sink, bufs, -1, 0);
tryBadWrite(sink, bufs, 0, 1000);
tryBadWrite(sink, bufs, 1000, 1);
tryBadRead(source, bufs, 0, -1);
tryBadRead(source, bufs, -1, 0);
tryBadRead(source, bufs, 0, 1000);
tryBadRead(source, bufs, 1000, 1);
sink.close();
source.close();
}
static void testFileVectorParams() throws Exception {
File testFile = File.createTempFile("filevec", null);
testFile.deleteOnExit();
RandomAccessFile raf = new RandomAccessFile(testFile, "rw");
FileChannel fc = raf.getChannel();
tryBadWrite(fc, bufs, 0, -1);
tryBadWrite(fc, bufs, -1, 0);
tryBadWrite(fc, bufs, 0, 1000);
tryBadWrite(fc, bufs, 1000, 1);
tryBadRead(fc, bufs, 0, -1);
tryBadRead(fc, bufs, -1, 0);
tryBadRead(fc, bufs, 0, 1000);
tryBadRead(fc, bufs, 1000, 1);
fc.close();
}
private static void tryBadWrite(GatheringByteChannel gbc,
ByteBuffer[] bufs, int offset, int len)
throws Exception
{
try {
gbc.write(bufs, offset, len);
throw new RuntimeException("Expected exception not thrown");
} catch (IndexOutOfBoundsException ioobe) {
// Correct result
}
}
private static void tryBadRead(ScatteringByteChannel sbc,
ByteBuffer[] bufs, int offset, int len)
throws Exception
{
try {
sbc.read(bufs, offset, len);
throw new RuntimeException("Expected exception not thrown");
} catch (IndexOutOfBoundsException ioobe) {
// Correct result
}
}
}

View file

@ -0,0 +1,132 @@
/*
* Copyright (c) 2003, 2010, 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.
*/
/* @test
* @bug 4854354
* @summary Test vector write faster than can be read
* @library ..
*/
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class Write {
static Random generator = new Random();
static int testSize = 15;
public static void main(String[] args) throws Exception {
WriteServer sv = new WriteServer();
sv.start();
bufferTest(sv.port());
if (sv.finish(8000) == 0)
throw new Exception("Failed" );
}
static void bufferTest(int port) throws Exception {
ByteBuffer[] bufs = new ByteBuffer[testSize];
for(int i=0; i<testSize; i++) {
String source =
"a muchmuchmuchmuchmuchmuchmuchmuch larger buffer numbered " +
i;
bufs[i] = ByteBuffer.allocateDirect(source.length());
}
// Get a connection to the server
InetAddress lh = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(lh, port);
SocketChannel sc = SocketChannel.open();
sc.connect(isa);
sc.configureBlocking(false);
// Try to overflow the socket buffer
long total = 0;
for (int i=0; i<100; i++) {
long bytesWritten = sc.write(bufs);
if (bytesWritten > 0)
total += bytesWritten;
for(int j=0; j<testSize; j++)
bufs[j].rewind();
}
// Clean up
sc.close();
}
}
class WriteServer extends TestThread {
static Random generator = new Random();
final ServerSocketChannel ssc;
WriteServer() throws IOException {
super("WriteServer");
this.ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0));
}
int port() {
return ssc.socket().getLocalPort();
}
void go() throws Exception {
bufferTest();
}
void bufferTest() throws Exception {
ByteBuffer buf = ByteBuffer.allocateDirect(5);
// Get a connection from client
SocketChannel sc = null;
try {
ssc.configureBlocking(false);
for (;;) {
sc = ssc.accept();
if (sc != null)
break;
Thread.sleep(50);
}
// I'm a slow reader...
Thread.sleep(3000);
} finally {
// Clean up
ssc.close();
if (sc != null)
sc.close();
}
}
}