2011-06-13 28 views
4

我有一個名爲「clientSock」的套接字。它已連接並正在工作。使用套接字手動發送Keep-Alive包

我收到使用一個線程循環的數據,如下所示:

char[] inputChars = new char[1024]; 
int charsRead = 0; 

    while (!stopNow) { 

     try { 

      if ((charsRead = inputStream.read(inputChars)) != -1) 
       { 

        System.out.println("Firing"); 
        fire_dataRecieved(new String(inputChars, 0, charsRead)); //Fire event. 
       } 

      } catch (IOException e) { 
       //CLIENT HAS DISCONNECTED... 
       connectedClient.disconnect(); 
       stopNow(); 
      } 
     } 

我想發送的「保持活動包」,只需發送「#保活」到另一端。

我可以使用sendStream.print("#KEEP-ALIVE")來做到這一點。有沒有更好的方法來做到這一點?如果沒有,是否有一種有效的方法來檢查你是否得到了數據包?或者已經有的東西可以讓你檢查另一端是否還活着? clientSock.setKeepAlive(true)不會爲我剪下它。我需要檢查另一端是否按需提供。

+0

一個選項是在客戶端套接字上設置讀取超時(http://download.oracle.com/javase/6/docs/api/java/net/Socket.html#setSoTimeout%28int%29) 。你使用'linux'是否是 – mre 2011-06-13 12:00:23

+0

?在Linux中,默認保持活動時間是** 2小時**。 – 2011-06-13 12:19:11

+0

「手動」和「按需」意味着我想發送保持活力*只要我想*,而不是每兩個小時。 – David 2011-06-13 12:39:33

回答

1

有沒有更好的方法來做到這一點? 如果不是, 是否有效的方式檢查你是否得到了數據包?或 東西已經存在,允許您檢查 是否存在 ?

如果連接出現問題,當您發送自己的保持活動數據包時,TCP堆棧會很快告訴您。它包含一個方法來檢查數據包是否以正確的順序到達。

現在,如果您想明確確認您的數據包已收到,您應該讓另一端發回確認。這是過分的恕我直言,但這就是你必須做的。

如果你沒有在合理的延遲時間內得到響應(10秒以上),並且如果TCP堆棧沒有拋出某種錯誤,這意味着另一方的聆聽方/應用程序沒有做它的工作。問題出現在應用程序級別,而不是TCP堆棧級別。

+1

非常好的答案。我知道TCP棧應該處理它,但我也希望100%確定應用程序層正在完成它的工作。 – David 2011-06-13 14:02:28

1

我不確定這裏有什麼問題。
如果另一端在網絡級別關閉,您將在嘗試從輸入流中讀取時收到異常。
如果另一端具有端口綁定,但在應用程序級別存在問題以禁止應用程序響應,那麼可以使用JVestry提到的ACK
除非您的問題是您需要區分間歇性網絡故障和服務器應用程序處於脫機狀態。