DatagramSocket关闭后,端口仍然使用

时间:2011-12-29 04:08:24

标签: java sockets udp

以下代码可以重现此问题:       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方法没有立即关闭本机套接字?

3 个答案:

答案 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套接字流失。