2010-05-19 49 views
0

我有接受通過客戶端套接字進行的連接上,我需要從該客戶端套接字讀取輸入,現在假設客戶開到我的服務器的連接,而通過服務器的發送任何一個服務器上運行socket outputstream,在這種情況下,當我的服務器試圖通過客戶端套接字的輸入流讀取輸入時,會拋出一個異常,但在拋出異常之前,我希望超時時間爲5秒,我該怎麼做?目前這裏是我的代碼看起來像在服務器端:設置超時的InputStreamReader變量

try 
    { 
     InputStreamReader clientInputStream = new InputStreamReader(clientSocket.getInputStream()); 
     int c; 
     StringBuffer requestBuffer = new StringBuffer(); 
     while ((c = clientInputStream.read()) != -1) 
     { 
      requestBuffer.append((char) c); 
      if (requestBuffer.toString().endsWith(("\r\n\r\n"))) 
       break; 
     } 
     request = new Request(requestBuffer.toString(), clientSocket); 
    } 
    catch (Exception e) // catch any possible exception in order to keep the thread running 
    { 
     try 
     { 
      if (clientSocket != null) 
       clientSocket.close(); 
     } catch (IOException ex) 
     { 
      ex.printStackTrace(); 
     } 
     System.err.println(e); 
     //e.printStackTrace(); 
    } 

回答

0

您是否嘗試過底層套接字上設置超時?請參閱Socket.setSoTimeout()。從DOC:

使用此選項設置爲非零 超時,與此 套接字關聯的 InputStream的一個read()調用將阻塞,僅此時間量 。如果超時,一個 java.net.SocketTimeoutException是 提出,雖然Socket仍舊 有效

+0

沒有,但我現在試着這樣做: clientSocket.setSoTimeout(5000); 但是異常仍然立即拋出。 – Noona 2010-05-19 22:37:53

+0

什麼是異常類和消息? – mdma 2010-05-19 22:53:02

+0

java.net.SocketException異常:連接復位 其來源是這一行: 而((C = clientInputStream.read())!= -1) – Noona 2010-05-19 22:55:43

3

教科書答案是設置soTimeout您的插座,你可以做。但是,這並不適用於所有情況。我的一位朋友曾經通過拉出我的網線來證明這一點。我設置了soTimeout,值爲30秒,但我的應用程序只是永遠掛在那裏。

要獲取可靠的超時,最好是你的I/O劃分到花葯線程。如果線程在給定的時間內沒有返回響應,您可以嘗試中斷它,關閉流並最終銷燬線程。這不會讓你更進一步,但會嘗試清理流。一旦發生超時,您需要考慮當前的通信丟失,重新建立連接並重新發送先前的命令以重複通信。 A command-pattern可以在這裏幫助。如果命令是冪等性的並且可以多次執行,那麼執行起來會更容易。能夠重複失敗的請求可用於處理間歇性I/O錯誤。

+0

目前我有這個代碼運行在一個單獨的線程。 – Noona 2010-05-19 22:39:19

+0

很好,然後setSoTimeout,它大多數時間工作,但也準備打斷你的線程,如果它不及時回來。請注意,在某些情況下,即使中斷也不會讓你的線程等待I/O(我知道它應該,但在實踐中它不會),所以如果中斷不能讓你回到控制,準備好關閉流,拋開線程並重新開始一個新的連接。 – mdma 2010-05-19 22:46:03

+0

我想讓線程繼續運行,因爲它包含在我準備並啓動服務器時啓動的線程池中。並在我對布賴恩的評論中表示,異常仍然立即拋出。 – Noona 2010-05-19 22:51:15