diff -r 252e7f4c4d92 -r 705c3f88a409 src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Oct 09 09:23:22 2019 -0700 +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java Wed Oct 09 17:38:58 2019 +0100 @@ -875,6 +875,11 @@ if (state == ST_CONNECTED) throw new AlreadyConnectedException(); + // ensure that the socket is bound + if (localAddress == null) { + bindInternal(null); + } + int n = Net.connect(family, fd, isa.getAddress(), @@ -932,8 +937,21 @@ remoteAddress = null; state = ST_UNCONNECTED; - // refresh local address - localAddress = Net.localAddress(fd); + // check whether rebind is needed + InetSocketAddress isa = Net.localAddress(fd); + if (isa.getPort() == 0) { + // On Linux, if bound to ephemeral port, + // disconnect does not preserve that port. + // In this case, try to rebind to the previous port. + int port = localAddress.getPort(); + localAddress = isa; // in case Net.bind fails + Net.bind(family, fd, isa.getAddress(), port); + isa = Net.localAddress(fd); // refresh address + assert isa.getPort() == port; + } + + // refresh localAddress + localAddress = isa; } } finally { writeLock.unlock();