2013-03-11 39 views
4

我覺得我錯過了這裏真正明顯的東西。如何在不使用選擇器的情況下實現阻止DatagramChannel的超時處理

我的系統的整體結構讓我想要使用阻塞DatagramChannel而不使用選擇器,以保持簡單。 我想通過在套接字上設置超時來實現超時處理,但這似乎沒有效果。

這個僞代碼給出了我想要實現的一些提示。另一方面,我有一個UDP服務器,它提供五個快速響應,然後,爲了測試目的,在傳遞第六個響應之前延遲大約五秒鐘。

延遲不會觸發SocketTimeoutException。這是爲什麼?調用channel.receive時,套接字上設置的超時值似乎沒有考慮到。

問候, 弗雷德裏克

+0

我最近發現setSoTimeout()不適用於SocketChannel讀取,它看起來也不適用於DatagramChannels。爲什麼,我無法想象。有沒有理由不能使用DatagramSocket? – EJP 2013-03-11 12:03:08

+0

沒理由。只是認爲DatagramChannel看起來更好。 – 2013-03-11 12:58:53

+0

它確實,但它有這個奇怪的* lacuna。* – EJP 2013-03-12 03:41:42

回答

2

顯然不能夠超時的問題是不是與DatagramChannel的錯誤,但:

不是一個錯誤。 SocketChannel(和DatagramChannel)中的讀取方法不支持超時。如果您需要超時功能,請使用關聯的Socket(或DatagramSocket)對象的讀取方法 。

Link.

+0

謝謝。我覺得這完全是離奇的。 – EJP 2013-10-14 23:00:04

+1

我必須在那裏同意你的看法。我只是自己學習SocketChannels,所以我們應該使用Selector來代替? – Kerry 2013-10-15 11:10:44

+1

顯然,但這也迫使你使用非阻塞模式。它仍然很古怪。讀取超時沒有理由不被支持。套接字是C層的套接字。 – EJP 2013-11-09 01:05:13

0

這是我做過什麼:

創建Interrupter

static private class Interrupter implements Runnable 
{ 
    private final Thread th1; 
    private volatile int wait=-1; 
    private Interrupter(Thread ith1) 
    { 
     th1=ith1; 
    } 
    public void run() 
    { 
     while(true) 
     { 
      try{ 
       if(wait<0){ th1.join(); break; } 
       else{ Thread.sleep(wait); th1.interrupt(); wait=-1; } 
      } catch(Exception e){} 
     } 
    } 
} 

設置的Interrupter

Interrupter ir1=new Interrupter(Thread.currentThread()); 
Thread th1=new Thread(ir1); 
th1.start(); 
// We need this so that later the wait variable 
// can be passed in successfully 
while(th1.getState()!=Thread.State.WAITING); 

使用Interrupter

try{ 
    ir1.wait=waitTimeout; 
    th1.interrupt(); 
    // Receive on the socket 
    dc2.receive(bb2); 
} catch(ClosedByInterruptException e){ 
    // (Timed out) 
    Thread.interrupted(); 
    dc2.close(); 
    // Handle timeout here 
    // ... 
    // We need this so that later the wait variable 
    // can be passed in successfully 
    while(th1.getState()!=Thread.State.WAITING); 
} 
// Received packet 
ir1.wait=-1; 
th1.interrupt(); 
// We need this so that later the wait variable 
// can be passed in successfully 
while(th1.getState()!=Thread.State.WAITING); 
Thread.interrupted(); 
相關問題