DatagramChannel.close () сохраняет порт открытым в Windows

m реализует процесс Discover, который:

Откройте сокет UDP для прослушивания широковещательного ответа на данный портОтправить несколько запросов (и ожидать ответа позже)Закройте сокет UDP через определенный промежуток времени

Первый звонок работает. Но другой вызов получает ошибку связывания. Адрес уже используется: bindI '

Я запустил Windows 7. Я провел несколько тестов и обнаружил, что после channel.close (); Netstat все еще дает:

netstat -a -b -sp udp | grep 55224

UDP 0.0.0.0:55224:

Так что порт udp все еще открыт на уровне ОС

Я искал в Интернете, и это может быть утечка на уровне ОС:Некоторые вопросы Java Datagram Socket

Я провел 2 теста, один с использованием канала NIO, а другой без (из теста, найденного в Интернете). Я воспроизвожу свою ошибку с версией NIO, но она работает, если я не использую NIO.

Я любой могу указать мне, как я могу сделать это работает с NIO. Целевой платформой является Android, где я надеваюt want всегда слушать трансляцию, но только в течение повторяющегося периода времени.

Тестовая розетка
    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...");

}
РЕЗУЛЬТАТ РАССЕТА <

начало ... Ошибка (при = 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...");

}

ПРИМЕЧАНИЕ: если канал.register прокомментирован, тестовые работы

РЕЗУЛЬТАТ С КАНАЛОМ

начало ... Ошибка (при = 0) (ожидание = 0 мс): ноль Ошибка (при = 0) (ожидание = 50 мс): адрес уже используется: bind

Ошибка (при = 0) (ожидание = 100 мс): адрес уже используется: bind

Ошибка (при = 0) (ожидание = 150 мс): адрес уже используется: bind ...

Спасибо за любую помощь

Ответы на вопрос(2)

Ваш ответ на вопрос