结合多次到同一个端口?(Binding multiple times to the same por

2019-08-05 08:51发布

为什么不将下面的代码抛出一个“java.net.BindException:地址已在使用:JVM_Bind”异常?

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);
        }
    }
}

运行“netstat的”事后显示:

  C:\用户\管理员>的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听力 

我的Windows Server 2008 R2(64位)上运行这一点,“IPCONFIG / ALL”显示只有一个网络适配器/接口(其它网卡被禁用)。 但是,一些其他的机器,这个程序实际上不会抛出预期“java.net.BindException:地址已在使用中:JVM_Bind”!

可能是什么回事?

Answer 1:

你可以对不同的IP地址相同的端口号进行绑定。 操作系统可以通过他们的目标IP地址以及它们的TCP端口号区分传入分组。

操作系统没有问题保持单独的ServerSocket为127.0.0.1:1000127.0.0.2:1000 。 它知道每个数据包所属的 - 即使它会打开一个新的连接。

需要注意的是IP地址0.0.0.0就是这样-一个IP地址(这是不是在这个意义上的IP数据包的有效 IP地址可以被发送到那里,但我不能为任何支持0.0.0.0 == any其一)。 如果你想监听所有地址,供null的,而不是的InetSocketAddress。 在这一点上,你获得所需的异常的机会较大(除非OS决定通配符监听具有较低的优先级和真的不重叠具体监听,这样他们就可以结合两者)。

另外请注意,设置setReuseAddress不会影响结合。 它不仅影响了什么连接得到拒绝或接受的一些细节。

作为一个侧面说明 - 什么是等待3亿年点?



文章来源: Binding multiple times to the same port?