2011-01-12 5 views
14

Ich bin eine Anwendung erstellen, die TCP und UDP überwacht, und ich habe einige Probleme mit meinem Shutdown-Mechanismus gerannt. Wenn ich auf jedem der zuhörenden Threads Thread.interrupt() aufrufen, wird der TCP-Thread vom Abhören unterbrochen, während der UDP-Listener dies nicht tut. Um genau zu sein, verwendet der TCP-Thread ServerSocket.accept(), der einfach zurückkehrt (ohne tatsächlich zu verbinden). Während der UDP-Thread DatagramSocket.receive() verwendet und diese Methode nicht beendet.Unterbrechen Sie einen Thread in DatagramSocket.receive

Ist dies ein Problem in meiner JRE, meinem Betriebssystem, oder sollte ich nur auf (Datagram)Socket.close() wechseln?

UPDATE: Ich habe eine analysis des Problems gefunden. Es bestätigt, dass das Verhalten nicht konsistent ist.

+0

Nur um anderen zu helfen, die sich mit dem gleichen Problem befassen: Mein 'ServerSocket.accept()' kam nicht ohne Verbindung zurück. Es wurde zurückgegeben, weil mein Browser (FF4b10) das Favicon dreimal anfordert. Eine der Anfragen war die Überprüfung von Thread.interrupted(). Ich wechsle auf 'close()' um. – SEK

Antwort

26

Ein gängiges Idiom zum Unterbrechen der Netzwerk-IO ist das Schließen des Kanals. Das wäre eine gute Wette, wenn Sie es effektiv unterbrechen müssen, während Sie auf Senden oder Empfangen warten.

public class InterruptableUDPThread extends Thread{ 

    private final DatagramSocket socket; 

    public InterruptableUDPThread(DatagramSocket socket){ 
     this.socket = socket; 
    } 
    @Override 
    public void interrupt(){ 
    super.interrupt(); 
    this.socket.close(); 
    } 
} 
+0

Konnte es nicht besser selbst formuliert haben. Vielen Dank! – SEK

0

DatagramSocket.receive blockiert, bis es ein Datagramm empfängt. Wahrscheinlich, was Sie tun müssen, ist setSoTimeout, um es Timeout zu machen.

+0

Timeout ist in diesem Fall keine akzeptable Lösung. Außerdem sollte 'DatagramSocket.receive()' unterbrochen werden, weshalb das seltsam ist. – SEK

+1

@SEK: Nein sollte es nicht. Es gibt nichts im Javadoc, das das sagt. Wenn Sie unterbrechbares Verhalten wünschen, müssen Sie DatagramChannel verwenden, das InterruptibleChannel implementiert. – EJP

2

Soweit ich weiß, ist close() der richtige Weg, eine blockierte Steckdose zu unterbrechen. Das Unterbrechen und Offenhalten von etwas, das bereits teilweise gelesen oder geschrieben hat, macht die Dinge unnötig komplex. Es ist einfacher, nur mit einem Ergebnis "Erfolg" oder "Aufgeben" fertig zu werden.

Verwandte Themen