DatagramChannel.close()保持开放口岸在Windows(DatagramChan

2019-08-01 15:58发布

我实现一个探索的过程是:

  • 打开一个UDP套接字来侦听特定端口上广播响应
  • 发送一些请求(预计后期响应)
  • 给定的时间段后,关闭UDP套接字

第一次调用工作。 但其他呼叫得到一个绑定错误。 地址已在使用:绑定

我运行Windows 7我做了一些测试,发现一个channel.close后(); 用netstat仍然给:

netstat的 - -b -SP UDP | grep的55224

UDP 0.0.0.0:55224:

因此,UDP端口是在操作系统级别仍然打开

我在网上搜索,它可能是在操作系统级别的泄漏: 一些Java数据报套接字问题

我跑使用NIO信道和一个没有2个测试之一(在网络上发现了一个试验)。 我重现我的错误与NIO版本,但它的工作原理,如果我不`吨使用NIO。

我任何人都可以点我怎么可以把它的工作原理与NIO。 作为目标的平台就是Android在那里我不t wan吨至时刻聆听广播,但仅持续重复周期。

测试插座

    public void testConnectCloseWithSocket() {
    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;
            try {
                Thread.sleep(50);
            } catch (InterruptedException e1) {


            }
            i--;
        }
    }
    System.out.println("end...");

}

RESULT插座<

开始...错误(= 1319)(等待= 0毫秒):地址已在使用:无法绑定

错误(= 1438)(等待= 0毫秒):地址已在使用:无法绑定

错误(= 1587)(等待= 0毫秒):地址已在使用:无法绑定

错误(= 1740)(等待= 0毫秒):地址已在使用:无法绑定

结束...


我没有得到一些错误,但插座得到正确关闭......这是OKI我的需要

与信道测试

    public void testConnectCloseWithChannel() {
    long tCumulative = 0;
    int errAt = -1;
    System.out.println("start...");
    for (int i = 0; i < 4000; i++) {
        try {
            errAt = i;
            Selector selector = Selector.open();
            DatagramChannel channel = DatagramChannel.open();
            channel.configureBlocking(true);
            channel.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 9005));
            SelectionKey clientKey = channel.register(selector, SelectionKey.OP_READ);
            clientKey.cancel();
            channel.close();

            //success at last
            tCumulative = 0;

        } catch (Exception e) {
            System.out.println("Error (at="+errAt+") (waited="+tCumulative+"ms): " + e.getMessage());

            tCumulative+=50;
            try {
                Thread.sleep(tCumulative);
            } catch (InterruptedException e1) {


            }
            i--;
        }
    }
    System.out.println("end...");

}

注:该channel.register被注释掉的测试工作..


与CHANNEL结果

开始...错误(= 0)(等待= 0毫秒):零错误(= 0)(等待= 50毫秒):地址已在使用:绑定

错误(= O)(等待= 100毫秒):已在使用的地址:绑定

错误(= 0)(等待= 150毫秒):地址已在使用:绑定...


谢谢你的帮助

Answer 1:

我没有得到一些错误,但插座得到正确关闭......这是OKI我的需要

不,如果你有错误,你的通道没有正确关闭。

你所要做的close了在finally您的从句try块。

Selector selector = Selector.open();
try
{
  DatagramChannel channel = DatagramChannel.open();

  try
  {
    channel.configureBlocking(true);
    channel.socket().bind(
      new InetSocketAddress(InetAddress.getLocalHost(), 9005)
    );
    SelectionKey clientKey = channel.register(selector, SelectionKey.OP_READ);
    clientKey.cancel();
  }
  finally
  {
    channel.close();
  }
}
finally
{
  selector.close( )
}


Answer 2:

如果信道与选择器中注册的信道关闭的某些部分被推迟至下一个选择()。 这是在选择,AbstractSelector,SelectorSpi,SelectableChannel中,AbstractSelectableChannel,森林,我永远无法找到它,当我需要它的地方记录。 如果你选择循环和线程中,当你关闭通道,你可以把它直接调用selectNow()。



文章来源: DatagramChannel.close() keeps port open on Windows
标签: java udp nio