DatagramChannel.close () hält den Port unter Windows offen

Ich implementiere einen Discover-Prozess, der:

Öffnen Sie einen UDP-Socket, um auf Broadcast-Antworten an einem bestimmten Port zu wartenSenden Sie einige Anfragen (und erwarten Sie eine spätere Antwort)Schließen Sie den UDP-Socket nach einer bestimmten Zeit

Der erste Anruf funktioniert. Bei anderen Aufrufen tritt jedoch ein Bindefehler auf. Bereits verwendete Adresse: binden

Ich verwende Windows 7. Ich habe einige Tests durchgeführt und festgestellt, dass nach einem channel.close (); Netstat gibt noch:

netstat -a -b -sp udp | grep 55224

UDP 0.0.0.0:55224:

Der udp-Port ist also immer noch auf Betriebssystemebene geöffnet

Ich habe im Internet gesucht und es könnte ein Leck auf Betriebssystemebene sein:Einige Java Datagram Socket Fragen

Ich habe 2 Tests durchgeführt, einen mit NIO-Kanal und einen ohne (aus einem Test im Internet). Ich reproduziere meinen Fehler mit der NIO-Version, aber es funktioniert, wenn ich NIO nicht verwende.

Ich jeder kann mir zeigen, wie ich es mit NIO machen kann. Die Zielplattform ist Android, auf der ich arbeitet want immer auf Sendung zu hören, aber nur für sich wiederholende Zeit.

PRÜFBUCHSE
    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...");

}
ERGEBNISSTECKDOSE <

start ... Error (at = 1319) (waited = 0ms): Adresse wird bereits verwendet: Kann nicht binden

Fehler (um = 1438) (gewartet = 0 ms): Adresse wird bereits verwendet: Kann nicht gebunden werden

Fehler (um = 1587) (gewartet = 0 ms): Bereits verwendete Adresse: Kann nicht gebunden werden

Fehler (um = 1740) (gewartet = 0 ms): Bereits verwendete Adresse: Kann nicht gebunden werden

Ende...

Ich habe einige Fehler bekommen, aber die Steckdose wurde richtig geschlossen ... was für meine Bedürfnisse ok ist

TEST MIT KANAL
    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...");

}

HINWEIS: Wenn das channel.register kommentiert ist, funktioniert der Test.

Ergebnis mit Kanal

start ... Fehler (at = 0) (waited = 0ms): null Fehler (at = 0) (waited = 50ms): Bereits verwendete Adresse: bind

Fehler (at = 0) (waited = 100ms): Adresse wird bereits verwendet: bind

Fehler (at = 0) (waited = 150ms): Adresse wird bereits verwendet: bind ...

Danke für jede Hilfe

Antworten auf die Frage(2)

Ihre Antwort auf die Frage