2011-01-12 134 views
3

我正在兩個站(A,B)之間建立標準TCP連接 A正在發送消息,B收到併發迴響應,然後關閉連接。爲DataInputStream設置手動超時

  • 工作站B是「黑匣子」,我無法訪問更改或在那裏做任何事情。

有時B有沒有發送迴應的情況,然後我需要重新嘗試整個過程。

我想在站A的等待時間(等待答案B)的收回時間上設置超時。 所以基本上當等待時間過期時,我會派遣一個重試。

我沒有找到一種方法來設置DataInputStream的超時。 (僅適用於全套接字連接 - 我不想)

一些代碼:

/** 
* Method receives the Server Response 
*/ 
public byte[] receive(DataInputStream is) throws Exception 
{ 
    logger.debug(TAG + " Client Recieving..."); 

    try 
    { 

     byte[] inputData = new byte[1024]; 
        // here I want to set timeout for the "receiving mode" 
     is.read(inputData); 
     return inputData; 
    } catch (Exception e) 
    { 
     throw new Exception(TAG + " Couldnt receive data from modem: " + e.getMessage()); 
    } 
} 

感謝, 射線。

回答

1

考慮使用非阻塞的SocketChannel而不是DataInputStream

實施例:

private static final long TIMEOUT = 500; 

/** 
* Method receives the Server Response 
*/ 
public <C extends SelectableChannel & ReadableByteChannel>byte[] 
receive(C chan) throws IOException 
{ 
    logger.debug(TAG + " Client Recieving..."); 
    try 
    { 
     Selector sel = Selector.open(); 
     SelectionKey key = chan.register(sel, SelectionKey.OP_READ); 
     ByteBuffer inputData = ByteBuffer.allocate(1024); 
     long timeout = TIMEOUT; 
     while (inputData.hasRemaining()) { 
      if (timeout < 0L) { 
       throw new IOException(String.format("Timed out, %d of %d bytes read", inputData.position(), inputData.limit())); 
      } 
      long startTime = System.nanoTime(); 
      sel.select(timeout); 
      long endTime = System.nanoTime(); 
      timeout -= TimeUnit.NANOSECONDS.toMillis(endTime - startTime); 
      if (sel.selectedKeys().contains(key)) { 
       chan.read(inputData); 
      } 
      sel.selectedKeys().clear(); 
     } 
     return inputData.array(); 
    } catch (Exception e) 
    { 
     throw new Exception(TAG + " Couldnt receive data from modem: " + e.getMessage()); 
    } 
} 
1

首先檢查了socket.setSoTimeout(timeout)

其次,看到這個討論:Is it possible to read from a InputStream with a timeout?

讀取方法被阻塞。檢查流是否包含沒有阻塞的數據的唯一方法是使用available()方法。因此,如果在n秒後沒有任何內容可用,您可以嘗試以某種延遲調用此方法並退出。您可以編寫自己的輸入流,以封裝實現此邏輯的任何其他輸入流。上面的參考顯示瞭如何做到這一點。