2017-04-12 9 views
2

Javaクライアントは常にJavaサーバーに接続されており、サーバーが送信したものを出力します(以下の抜粋を参照)。コンピュータ起床後のMacOSXでJavaソケット接続が壊れていることを認識する方法

問題は、クライアントコンピュータ(MacOS X)がスリープ状態になって再び起動すると、クライアントがin.readLine()でハングし、接続が壊れていることがわかりません。クライアントがreadLine()でブロックを停止し、実際にSocketTimeoutExceptionをスローするように、ソケットにSO_TIMEOUTを追加しましたが、壊れた接続から再度回線を読み込もうとします。

私の質問は以下のとおりです。なぜin.readLine()IOException(私は再起動、接続できるように)で失敗しないとどのように私は、クライアントは、Mac OS X上でawake->sleep->awakeサイクル上のサーバーに再接続することができますか?

Socket socket = new Socket(...); 
socket.setSoTimeout(10000); 
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
[...] 
while (true) { 
    try { 
     while ((serverSays = in.readLine()) != null) { 
      System.out.println("Server says: " + serverSays); 
     } 
    } catch (SocketTimeoutException e) { 
     continue; 
    } 
    // An exception other than SocketTimeoutException will break the while-loop. 
} 
// If another exception other than SocketTimeoutException occurs, 
// catch it and re-initiate the connection and start over. 

答えて

0

IOExceptionは、ローカルホストがリモートホストがデータを提供しなくなっていることを知っていないことを意味します。

SocketTimeoutExceptionは、リモートホストが割り当てられた時間内にデータを提供できなかったことを意味します。それは接続が正式にダウンしていることを私たちに言ったことはありません。

SocketTimeoutException正常に接続が閉じられなかった場合に発生します。リモートホストの電源が切れた場合、または誰かがイーサネットケーブルを抜いてしまった場合、それがあなたの手に入ります。

この場合、寝ている間、リモートホストは接続を終了する必要がありますが、ホストは通知を逃してスリープしています。

解決策は、一定数のタイムアウト後に接続が切断されたと想定することです。

-1

あなたはソケットが壊れた場合はタイムアウトを使用して再接続する必要がある場合は、これを試してみてください。

Socket socket = new Socket(...); 
socket.setSoTimeout(10000); 
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
[...] 
while (true) { 
    try { 
     while ((serverSays = in.readLine()) != null) { 
      System.out.println("Server says: " + serverSays); 
     } 
    } catch (SocketTimeoutException e) { 
     continue; 
    } catch (IOException e) { 
     //reconnecting with new Socket object and new reader, because old stream closed 
     socket = new Socket(...); 
     socket.setSoTimeout(10000); 
     in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    } 
} 
+0

問題は、 'IOException'は投げられないということです。 'SocketTimeoutException'をスローした後、何度も何度も読み直そうとします。反対側のサーバーを強制終了しても、クライアントは(IOExceptionをスローせずに)行を読み込もうとします。 –

+0

この接続に対してpingを実行できます。シンプルなデータをサーバーに送信してみてください。成功すれば、接続は生きています。そうでなければ、2番目のcatchブロックでソケットを閉じてコードを実行します。 –

+0

あなたはsocket.isConnected()をチェックすることができますが、それが役立つかどうかはわかりません。 –

関連する問題