2011-01-12 40 views
14

我正在構建一個偵聽TCP和UDP的應用程序,並且我遇到了一些關機機制的問題。當我在每個偵聽線程上調用Thread.interrupt()時,TCP線程會中斷偵聽,而UDP偵聽器不會。具體來說,TCP線程使用ServerSocket.accept(),它只是返回(不實際連接)。而UDP線程使用DatagramSocket.receive(),並且不會退出該方法。中斷DatagramSocket.receive中的線程

這是我的JRE,我的操作系統的問題,還是應該切換到(Datagram)Socket.close()

更新:我發現了一個analysis的問題。它證實了這種行爲並不一致。

+0

只是爲了幫助其他人處理相同的問題:我的`ServerSocket.accept()`沒有連接沒有返回。它正在返回,因爲我的瀏覽器(FF4b10)3次請求收藏夾圖標。其中一個請求是絆倒Thread.interrupted()檢查。我將切換到使用`close()`。 – SEK 2011-01-12 16:17:09

回答

26

中斷網絡IO的常用方式是關閉通道。如果您在等待發送或接收時需要有效打斷它,那將是一個不錯的選擇。

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

DatagramSocket.receive阻塞,直到它收到一個數據報。可能你需要做的是使用setSoTimeout來使其超時。

+0

超時在這種情況下不是可接受的解決方案。另外,DatagramSocket.receive()應該被中斷,這就是奇怪的原因。 – SEK 2011-01-12 15:57:57

+1

@SEK:不,它不應該。 Javadoc沒有這樣說。如果你想要可中斷的行爲,你需要使用DatagramChannel,它實現了InterruptibleChannel。 – EJP 2011-01-13 05:20:46

2

據我所知,close()是中斷被阻塞的套接字的正確方法。中斷並保持開放可能已經完成了部分讀取或寫入的事情會使事情變得不必要的複雜。只需處理「成功」或「放棄」的結果就容易多了。