Why doesn't the following code throw a "java.net.BindException: Address already in use: JVM_Bind" exception?
import java.net.InetSocketAddress;
import java.net.ServerSocket;
public class Test
{
public static void main(String[] args) throws Exception
{
try (ServerSocket socket1 = new ServerSocket();
ServerSocket socket2 = new ServerSocket();
ServerSocket socket3 = new ServerSocket())
{
int port = 10000;
socket1.setReuseAddress(false);
socket1.bind(new InetSocketAddress("0.0.0.0", port));
socket2.setReuseAddress(false);
socket2.bind(new InetSocketAddress("127.0.0.1", port));
socket3.setReuseAddress(false);
socket3.bind(new InetSocketAddress("127.0.0.2", port));
Thread.sleep(Long.MAX_VALUE);
}
}
}
Running 'netstat' afterwards displays:
C:\Users\Administrator>netstat -a -n | findstr 10000 TCP 0.0.0.0:10000 0.0.0.0:0 LISTENING TCP 127.0.0.1:10000 0.0.0.0:0 LISTENING TCP 127.0.0.2:10000 0.0.0.0:0 LISTENING TCP [::]:10000 [::]:0 LISTENING
I am running this on Windows Server 2008 R2 (64-bit), and 'ipconfig /all' displays only one network adapter/interface (other network adapters are disabled). But, on some other machines, this program actually does throw the expected "java.net.BindException: Address already in use: JVM_Bind"!
What could be going on?
You can bind on the same port number on different IP addresses. The operating system can distinguish the incoming packets by their target IP address as well as their TCP port number.
The operating system has no problem keeping a separate serverSocket for 127.0.0.1:1000
and 127.0.0.2:1000
. It knows where each packet belongs - even if it opens a new connection.
Note that the IP address 0.0.0.0
is just that - an IP address (it is not a valid IP address in the sense IP packets could be sent there, but I can't any support for 0.0.0.0 == any
either). If you want to listen on all addresses, supply null
to the InetSocketAddress instead. At this point, you have a greater chance of getting the desired exception (unless the OS decides that wildcard listens have lower priority and don't really overlap specific listens, so they can bind both).
Also note that setting setReuseAddress
will not affect the binding. It only affects some specifics of what connections get refused or accepted.
As a side note - what's the point of waiting three hundred million years?
来源:https://stackoverflow.com/questions/14132568/binding-multiple-times-to-the-same-port