为什么Windows Java无法绑定到已绑定的端口?

问题描述:

我们需要在响应请求时绑定到同一个本地端口。 以下是Java代码的示例。在Linux上,我们可以绑定两次相同的端口,但在Windows上,我们在第二次绑定时出错。错误是BindException:地址已被使用。用C编写的类似程序允许我们绑定两次。 防止Windows上的Java执行此操作的是什么?有没有注册表设置允许绑定?为什么Windows Java无法绑定到已绑定的端口?

import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.SocketAddress; 

public class SocketTest 
{ 
    public static void main(String[] args) throws Exception 
    { 
     Socket s1 = new Socket(); 
     s1.setReuseAddress(true); 
     SocketAddress saremote = new InetSocketAddress("google.com", 80); 
     SocketAddress salocal = new InetSocketAddress("10.1.1.98", 9990); 
     s1.bind(salocal); 
     s1.connect(saremote); 

     Socket s2 = new Socket(); 
     s2.setReuseAddress(true); 
     SocketAddress saremote2 = new InetSocketAddress("yahoo.com", 80); 
     SocketAddress salocal2 = new InetSocketAddress("10.1.1.98", 9990); 
     s2.bind(salocal2); 
     s2.connect(saremote2); 
    } 
} 
+1

套接字流连接是TCP,并且您只能使用TCP绑定到一个端口,然后必须先关闭连接,然后才能重新绑定到相同的端口 –

+0

C程序如何相似?我有这样的感觉,那里的不同部分是相关的。 – Joey

+0

你有*什么*需要?如果这是网络管理员在防火墙实施的所谓安全功能,请将其删除。安全性益处为零,并且使应用程序不可行。 – EJP

这在Linux和Windows上都可行。您可能有另一个应用程序(可能是您的应用程序的先前版本,它没有终止)运行并使用相同的端口。

+0

第一个绑定总是成功,所以端口可用。第二个绑定失败。 – user3375401

使用-Dsun.net.useExclusiveBind =假

目前已在Windows平台上的网络API实现的改变。 默认情况下,Windows上的网络API实施已更改为使用SO_EXCLUSIVEADDRUSE套接字选项。此更改对于解决在使用需要绑定到相同端口的IPv4和IPv6应用程序时出现的异常情况。

此更改可能会导致依赖于多个进程绑定到相同地址和端口的应用程序的问题。发生此类问题时,请使用sun.net.useExclusiveBind系统属性作为临时解决方法来恢复传统行为。