以下代码可以重现此问题: int errAt = -1;
try {
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
errAt = i;
DatagramSocket result = new DatagramSocket(null);
result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
result.close();
//System.out.println(i);
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
System.out.println("ErrAt: " + errAt);
e.printStackTrace();
} finally {
System.out.println("end...");
}
在我的电脑上,我会看到“java.net.BindException:地址已经在使用:无法绑定”异常运行2k次后。
我不确定,这是否意味着close方法没有立即关闭本机套接字?
答案 0 :(得分:2)
即使我将其设置为运行40,000次迭代,此代码也适用于我的Mac。我认为这里可能存在的问题是套接字没有立即在Windows上关闭,但是你又试图在大约几毫秒的时间内完成数千次迭代。
以下代码将不断重试并暂停一小段时间,以便让您了解套接字是否会在某段时间内关闭时出现延迟问题:
long tCumulative = 0;
int errAt = -1;
System.out.println("start...");
for (int i = 0; i < 4000; i++) {
try {
errAt = i;
DatagramSocket result = new DatagramSocket(null);
result.bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
result.close();
//success at last
tCumulative = 0;
} catch (Exception e) {
System.out.println("Error (at="+errAt+") (waited="+tCumulative+"ms): " + e.getMessage());
tCumulative+=50;
Thread.sleep(50);
i--;
}
}
System.out.println("end...");
答案 1 :(得分:1)
目前尚不清楚您要做什么,但解决仍在使用的UDP端口问题的一种方法是在绑定之前设置“重用地址”选项。
参考:How to set reuse address option for a datagram socket in java code?
答案 2 :(得分:1)
如果你创建套接字但是然后得到例如您没有关闭套接字的BindException。它应该在finally {}块中关闭。
很难看出这个测试的重点。普通的UDP程序打开一个 DatagramSocket
并在整个过程中保持打开状态。没有理智的程序会通过数千个UDP套接字流失。