-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
8, 11, 17, 18, 19
-
x86_64
-
windows_10
ADDITIONAL SYSTEM INFORMATION :
Windows 10 Pro[Version 10.0.19044 Build 19044]
Java 17
A DESCRIPTION OF THE PROBLEM :
When reuseAddress(true) is set on both client and server socket and then bound its works the first time but when running the client application an 2nd time throws address already in use exception
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Open an server socket on a separate JVM[Process]. set reuseAddress(true) on it before binding
2) Open an client socket connecting to this server on a separate JVM[Process.] set reuseAddress(true) on it before binding and connecting
3) Run the client process an 2nd time and it throws the exception
Procedure.
Before running the program we use netstat -aon | findstr in windows cmd to check for sockets running on an specific port
server=running on port 2500
client bounded to port 5000
netstat -aon | findstr 2500
<Nothing>
netstat -aon | findstr 2500
<Nothing>
a) We then run the server and check for its status on port 2500
netstat -aon | findstr 2500
TCP 192.168.1.2:2500 0.0.0.0:0 LISTENING 7676
b) We run the client and after it exits check the port 5000
netstat -aon | findstr 5000
TCP 192.168.1.2:5000 192.168.1.2:2500 TIME_WAIT 0
c) We also check the server again
netstat -aon | findstr 2500
TCP 192.168.1.2:2500 0.0.0.0:0 LISTENING 7676
TCP 192.168.1.2:5000 192.168.1.2:2500 TIME_WAIT 0
We can see the server is holding on to the client socket and the client socket is in TIME_WAIT state. The documentation of setReuseAddress clearly states
"When a TCP connection is closed the connection may remain in a timeout state for a period of time after the connection is closed (typically known as the TIME_WAIT state or 2MSL wait state). For applications using a well known socket address or port it may not be possible to bind a socket to the required SocketAddress if there is a connection in the timeout state involving the socket address or port.
Enabling SO_REUSEADDR prior to binding the socket using bind(SocketAddress) allows the socket to be bound even though a previous connection is in a timeout state."
Inspite of what it says running the client a 2nd time produces an bind exception address already in use
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error. Sockets should be able to reuse the address immediatly after closing without waiting 4 minutes for the socket in TIME_WAIT state to be removed
ACTUAL -
java.net.BindException: Address already in use: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:579)
at java.base/sun.nio.ch.Net.connect(Net.java:568)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:633)
at java.base/java.net.Socket.connect(Socket.java:583)
---------- BEGIN SOURCE ----------
Server. Run as an separate process
public static void main(String[] args)throws Exception
{
try(ServerSocket server=new ServerSocket())
{
server.setReuseAddress(true);
server.bind(new InetSocketAddress(InetAddress.getLocalHost(),2500));
while(true)
{
try(Socket client=server.accept())
{
//simple wait before closing
Thread.sleep(2000);
}
}
}
}
Client. Run as an separate process
public static void main(String[] args)throws Exception
{
try(Socket client=new Socket())
{
client.setReuseAddress(true);
client.bind(new InetSocketAddress(InetAddress.getLocalHost(),5000));
client.connect(new InetSocketAddress(InetAddress.getLocalHost(),2500));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
only way to terminate the client socket is client.setSoLinger(true,0) which crashes the server so is not an optimal solution
FREQUENCY : always
Windows 10 Pro[Version 10.0.19044 Build 19044]
Java 17
A DESCRIPTION OF THE PROBLEM :
When reuseAddress(true) is set on both client and server socket and then bound its works the first time but when running the client application an 2nd time throws address already in use exception
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Open an server socket on a separate JVM[Process]. set reuseAddress(true) on it before binding
2) Open an client socket connecting to this server on a separate JVM[Process.] set reuseAddress(true) on it before binding and connecting
3) Run the client process an 2nd time and it throws the exception
Procedure.
Before running the program we use netstat -aon | findstr in windows cmd to check for sockets running on an specific port
server=running on port 2500
client bounded to port 5000
netstat -aon | findstr 2500
<Nothing>
netstat -aon | findstr 2500
<Nothing>
a) We then run the server and check for its status on port 2500
netstat -aon | findstr 2500
TCP 192.168.1.2:2500 0.0.0.0:0 LISTENING 7676
b) We run the client and after it exits check the port 5000
netstat -aon | findstr 5000
TCP 192.168.1.2:5000 192.168.1.2:2500 TIME_WAIT 0
c) We also check the server again
netstat -aon | findstr 2500
TCP 192.168.1.2:2500 0.0.0.0:0 LISTENING 7676
TCP 192.168.1.2:5000 192.168.1.2:2500 TIME_WAIT 0
We can see the server is holding on to the client socket and the client socket is in TIME_WAIT state. The documentation of setReuseAddress clearly states
"When a TCP connection is closed the connection may remain in a timeout state for a period of time after the connection is closed (typically known as the TIME_WAIT state or 2MSL wait state). For applications using a well known socket address or port it may not be possible to bind a socket to the required SocketAddress if there is a connection in the timeout state involving the socket address or port.
Enabling SO_REUSEADDR prior to binding the socket using bind(SocketAddress) allows the socket to be bound even though a previous connection is in a timeout state."
Inspite of what it says running the client a 2nd time produces an bind exception address already in use
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error. Sockets should be able to reuse the address immediatly after closing without waiting 4 minutes for the socket in TIME_WAIT state to be removed
ACTUAL -
java.net.BindException: Address already in use: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:579)
at java.base/sun.nio.ch.Net.connect(Net.java:568)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:588)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:633)
at java.base/java.net.Socket.connect(Socket.java:583)
---------- BEGIN SOURCE ----------
Server. Run as an separate process
public static void main(String[] args)throws Exception
{
try(ServerSocket server=new ServerSocket())
{
server.setReuseAddress(true);
server.bind(new InetSocketAddress(InetAddress.getLocalHost(),2500));
while(true)
{
try(Socket client=server.accept())
{
//simple wait before closing
Thread.sleep(2000);
}
}
}
}
Client. Run as an separate process
public static void main(String[] args)throws Exception
{
try(Socket client=new Socket())
{
client.setReuseAddress(true);
client.bind(new InetSocketAddress(InetAddress.getLocalHost(),5000));
client.connect(new InetSocketAddress(InetAddress.getLocalHost(),2500));
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
only way to terminate the client socket is client.setSoLinger(true,0) which crashes the server so is not an optimal solution
FREQUENCY : always
- relates to
-
JDK-8286646 Connect should not throw BindException if the socket is bound
-
- Open
-