mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8343791: Socket.connect API should document whether the socket will be closed when hostname resolution fails or another error occurs
Reviewed-by: dfuchs, alanb
This commit is contained in:
parent
4ac2e477b9
commit
3eb5461578
5 changed files with 226 additions and 42 deletions
|
@ -454,6 +454,7 @@ public class Socket implements java.io.Closeable {
|
|||
throws IOException
|
||||
{
|
||||
Objects.requireNonNull(address);
|
||||
assert address instanceof InetSocketAddress;
|
||||
|
||||
// create the SocketImpl and the underlying socket
|
||||
SocketImpl impl = createImpl();
|
||||
|
@ -463,16 +464,13 @@ public class Socket implements java.io.Closeable {
|
|||
this.state = SOCKET_CREATED;
|
||||
|
||||
try {
|
||||
if (localAddr != null)
|
||||
if (localAddr != null) {
|
||||
bind(localAddr);
|
||||
connect(address);
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException ce) {
|
||||
e.addSuppressed(ce);
|
||||
}
|
||||
throw e;
|
||||
connect(address);
|
||||
} catch (Throwable throwable) {
|
||||
closeSuppressingExceptions(throwable);
|
||||
throw throwable;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -571,6 +569,10 @@ public class Socket implements java.io.Closeable {
|
|||
/**
|
||||
* Connects this socket to the server.
|
||||
*
|
||||
* <p> If the endpoint is an unresolved {@link InetSocketAddress}, or the
|
||||
* connection cannot be established, then the socket is closed, and an
|
||||
* {@link IOException} is thrown.
|
||||
*
|
||||
* <p> This method is {@linkplain Thread#interrupt() interruptible} in the
|
||||
* following circumstances:
|
||||
* <ol>
|
||||
|
@ -589,6 +591,8 @@ public class Socket implements java.io.Closeable {
|
|||
* @param endpoint the {@code SocketAddress}
|
||||
* @throws IOException if an error occurs during the connection, the socket
|
||||
* is already connected or the socket is closed
|
||||
* @throws UnknownHostException if the endpoint is an unresolved
|
||||
* {@link InetSocketAddress}
|
||||
* @throws java.nio.channels.IllegalBlockingModeException
|
||||
* if this socket has an associated channel,
|
||||
* and the channel is in non-blocking mode
|
||||
|
@ -605,6 +609,11 @@ public class Socket implements java.io.Closeable {
|
|||
* A timeout of zero is interpreted as an infinite timeout. The connection
|
||||
* will then block until established or an error occurs.
|
||||
*
|
||||
* <p> If the endpoint is an unresolved {@link InetSocketAddress}, the
|
||||
* connection cannot be established, or the timeout expires before the
|
||||
* connection is established, then the socket is closed, and an
|
||||
* {@link IOException} is thrown.
|
||||
*
|
||||
* <p> This method is {@linkplain Thread#interrupt() interruptible} in the
|
||||
* following circumstances:
|
||||
* <ol>
|
||||
|
@ -625,6 +634,8 @@ public class Socket implements java.io.Closeable {
|
|||
* @throws IOException if an error occurs during the connection, the socket
|
||||
* is already connected or the socket is closed
|
||||
* @throws SocketTimeoutException if timeout expires before connecting
|
||||
* @throws UnknownHostException if the endpoint is an unresolved
|
||||
* {@link InetSocketAddress}
|
||||
* @throws java.nio.channels.IllegalBlockingModeException
|
||||
* if this socket has an associated channel,
|
||||
* and the channel is in non-blocking mode
|
||||
|
@ -644,26 +655,25 @@ public class Socket implements java.io.Closeable {
|
|||
if (isClosed(s))
|
||||
throw new SocketException("Socket is closed");
|
||||
if (isConnected(s))
|
||||
throw new SocketException("already connected");
|
||||
throw new SocketException("Already connected");
|
||||
|
||||
if (!(endpoint instanceof InetSocketAddress epoint))
|
||||
throw new IllegalArgumentException("Unsupported address type");
|
||||
|
||||
if (epoint.isUnresolved()) {
|
||||
var uhe = new UnknownHostException(epoint.getHostName());
|
||||
closeSuppressingExceptions(uhe);
|
||||
throw uhe;
|
||||
}
|
||||
|
||||
InetAddress addr = epoint.getAddress();
|
||||
int port = epoint.getPort();
|
||||
checkAddress(addr, "connect");
|
||||
|
||||
try {
|
||||
getImpl().connect(epoint, timeout);
|
||||
} catch (SocketTimeoutException e) {
|
||||
throw e;
|
||||
} catch (InterruptedIOException e) {
|
||||
Thread thread = Thread.currentThread();
|
||||
if (thread.isVirtual() && thread.isInterrupted()) {
|
||||
close();
|
||||
throw new SocketException("Closed by interrupt");
|
||||
}
|
||||
throw e;
|
||||
} catch (IOException error) {
|
||||
closeSuppressingExceptions(error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
// connect will bind the socket if not previously bound
|
||||
|
@ -1589,6 +1599,14 @@ public class Socket implements java.io.Closeable {
|
|||
return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
|
||||
}
|
||||
|
||||
private void closeSuppressingExceptions(Throwable parentException) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException exception) {
|
||||
parentException.addSuppressed(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this socket.
|
||||
* <p>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue