DatagramChannel.close () mantém a porta aberta no Windows

Estou implementando um processo de Descoberta que:

Abra um soquete UDP para ouvir a resposta de transmissão em uma determinada portaEnvie algumas solicitações (e espere uma resposta posterior)Feche o soquete UDP após um determinado período de tempo

A primeira chamada funciona. Mas outra chamada recebe um erro de ligação. Endereço já em uso: bind

Estou executando o Windows 7. Fiz alguns testes e descobri que depois de um channel.close (); O Netstat ainda dá:

netstat -a -b -sp udp | grep 55224

UDP 0.0.0.0:55224:

Então a porta do udp ainda está aberta no nível do SO

Eu procurei na web e pode ser um vazamento no nível do SO:Algumas perguntas do soquete do datagrama de java

Eu corri 2 testes usando um canal NIO e um sem (a partir de um teste encontrado na web). Eu reproduzo meu erro com a versão NIO, mas funciona se eu não usar o NIO.

Qualquer um pode me mostrar como posso fazer isso funcionar com a NIO. A plataforma de destino é o Android, onde eu nãot want sempre ouvir a transmissão, mas apenas por um período de tempo repetitivo.

TESTE DE TESTE
    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...");

}
RESULTADO SOCKET <

start ... Erro (at = 1319) (esperado = 0ms): Endereço já em uso: não é possível ligar

Erro (at = 1438) (esperado = 0ms): Endereço já em uso: não é possível ligar

Erro (at = 1587) (esperado = 0ms): Endereço já em uso: não é possível ligar

Erro (at = 1740) (esperado = 0ms): endereço já em uso: não é possível vincular

fim...

Eu recebi alguns erros, mas o soquete foi fechado corretamente ... que é oki para minhas necessidades

TESTE COM CANAL
    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...");

}

NOTA: É o channel.register é comentado o teste funciona ..

RESULTADO COM CANAL

start ... Erro (at = 0) (esperado = 0ms): null Erro (at = 0) (esperado = 50ms): Endereço já em uso: bind

Erro (at = 0) (esperado = 100ms): Endereço já em uso: bind

Erro (at = 0) (esperado = 150ms): Endereço já em uso: bind ...

Obrigado por qualquer ajuda

questionAnswers(2)

yourAnswerToTheQuestion