SocketServer总是为动态端口引发BindException

时间:2016-04-06 17:49:24

标签: java windows sockets tcp tcpserver

  

解释
  众所周知的端口
端口号在[0,1023]中   注册端口
端口号在[1024,49151]中   动态端口
端口号,范围为[49152,65535]

我正在尝试创建一个SocketServer对象。当我允许SocketServer选择动态端口(通过绑定到端口0)时,它按预期工作。如果我明确指定了注册端口,它将按预期工作。但是,当我指定动态端口时,它总是抛出BindException,并显示消息“ Address已在使用中:JVM_Bind ”。异常的堆栈跟踪顶部是:

at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)

我在Windows 7 Enterprise SP1 x64计算机上使用JDK 1.8u74。代码如下:

SocketServer createServer(final int port) throws IOException {
    // Create a new socket server
    SocketServer server;
    try {
        // Try to bind to all interfaces
        server = new ServerSocket(port, 1, null);
    } catch (BindException e) {
        // If that fails, try to bind to the primary IP address
        final InetAddress address = InetAddress.getLocalHost();
        server = new ServerSocket(port, 1, address);
    }
    return server;
}

我也尝试了以下替代方案:

SocketServer createServer(final int port) throws IOException {
    // Create a new socket server
    final SocketServer server = new SocketServer();
    server.setReuseAddress(true);
    try {
        // Try to bind to all interfaces
        server.bind(new InetSocketAddress(port), 1);
    } catch (BindException e) {
        // If that fails, try to bind to the primary IP address
        final InetAddress address = InetAddress.getLocalHost();
        server.bind(new InetSocketAddress(address, port), 1);
    }
    return server;
}

port是动态端口时,这两种替代方法都会抛出BindException。我已经验证了我测试的所有大约50个动态端口都可以根据netstat -an的结果使用。有没有办法为特定的动态端口创建SocketServer

1 个答案:

答案 0 :(得分:0)

虽然不太理想,因为它涉及注册表编辑,但Server Fault提供了答案。

可以设置Windows以从其动态端口范围中排除端口。只需将要排除的范围添加到多字符串值:

  

HKLM \系统\ CurrentControlSet \服务\ TCPIP \参数\ ReservedPorts

所以,在我的情况下,我需要使用端口55101-55107,所以我将该文本添加到注册表值并重新启动计算机。虽然这个解决方案允许我使用这些端口,但令人失望的是我必须在我想要使用它们的任何Windows机器上编辑注册表。此外,如果我将来必须添加另一个动态端口,我将不得不重新编辑注册表。