我有带有自定义安全策略的Java应用程序,当我尝试打开100个udp套接字时,出现异常:
java.net.SocketException: maximum number of DatagramSockets reached
测试应用:
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.List;
public class Test {
static int basePortNum = 40000;
public static void main(String[] args) {
List socks = new ArrayList();
try{
for(int i = 0; i<100; i++){
socks.add(new DatagramSocket(basePortNum+i, Inet4Address.getByName("127.0.0.1")) );
System.out.println(i);
}
}catch(Exception e){
e.printStackTrace();
}finally{
for(java.net.DatagramSocket soc: socks){
soc.close();
}
}
}
}
如果我在没有安全管理器的情况下启动它,它将创建所有100个套接字:
0
1
...
98
99
但是如果我将此行添加到VM参数
-Djava.security.manager
即使使用默认的安全策略,它也会失败:
0
1
...
23
24
java.net.SocketException: maximum number of DatagramSockets reached
at sun.net.ResourceManager.beforeUdpCreate(ResourceManager.java:53)
at java.net.PlainDatagramSocketImpl.create(PlainDatagramSocketImpl.java:74)
at java.net.DatagramSocket.createImpl(DatagramSocket.java:318)
at java.net.DatagramSocket.(DatagramSocket.java:209)
at java.net.DatagramSocket.(DatagramSocket.java:262)
at Test.main(Test.java:16)
使用安全管理器时如何更改套接字限制?
UPD:在Windows 8.1 x64,Windows 7 x64和Windows XP SP3 x32,Windows 7 x32上复制.在所有系统上,均使用JDK 1.6.45 x32.
UPD2:在Windows xp sp3 x32上也用JDK7复制,但是不能用JDK 1.6.27复制.
UPD3:调试JDK类发现了这一点:
// Compiled from ResourceManager.java (version 1.5 : 49.0, super bit)
public class sun.net.ResourceManager {
// Field descriptor #14 I
private static final int DEFAULT_MAX_SOCKETS = 25;