1
  1. 2台のコンピューターがソケット接続で接続されています。サーバー/クライアントがそれらの端から接続を閉じる場合(つまり、、を閉じる場合InputStreamOutputStreamSocket切断についてもう一方の端に通知するにはどうすればよいですか?私が知っている1つの方法があります-if接続が閉じられている場合InputStreamにスローする、から読み取ろうとしますが、これを検出する他の方法はありますか?IOException
  2. 別の質問ですが、インターネットで問題を調べたところ、inputStream.available() この問題が解決しないことがわかりました。何故ですか?

追加情報:InputStrem切断を検出するためにから読み取ろうとすると、プロジェクトの処理が困難になるため、別の方法を求めて います。

4

4 に答える 4

7

IOExceptionをスローするInputStreamから読み取ろうとしています

それは正しくありません。ピアがソケットを閉じる場合:

  • read()-1を返します
  • readLine()nullを返します
  • readXXX()EOFException他のXの場合は、をスローします。

InputStreamメソッドしかないのでread()、-1を返すだけです。EOSではスローしませんIOException

ここでの他の回答とは異なり、ピアが接続を閉じたかどうかを通知するTCPAPIまたはSocketメソッドはありません。読み取りまたは書き込みを試す必要があります。

読み取りタイムアウトを使用する必要があります。

InputStream.available()いかなる種類のEOS表示も返さないため、問題は解決しません。それの正しい使用法はほとんどありません、そしてこれはそれらの1つではありません。

于 2012-09-03T08:18:25.200 に答える
0

接続が切断された瞬間にコールバック/例外を取得するOOOの方法はありません。ソケットストリームで明示的な読み取り/書き込みを行う場合にのみ、切断された接続について知ることができます。

ソケットから読み取るには2つの方法があります。到着時にバイトごとに同期して読み取ります。または、ストリームで使用可能なバイト数が必要になるまで待ってから、一括読み取りを実行します。チェックを行うには、ソケットストリームでavailable()を呼び出します。これにより、現在読み取り可能なバイト数がわかります。2番目のケースでは、何らかの理由でソケット接続が切断された場合、そのことを通知する方法はありません。その場合、待機にタイムアウトメカニズムを採用する必要があります。明示的な読み取り/書き込みを行う最初のケースでは、例外が発生します。

于 2012-09-03T07:58:02.057 に答える
0

Q1サーバーでソケット接続を閉じた場合、クライアントはすぐにではなくても例外をスローする必要があります。確実に次の読み取り試行で、その逆も同様です。

Q2JavaDocsから

この入力ストリームのメソッドの次の呼び出しによってブロックされることなく、この入力ストリームから読み取る(またはスキップする)ことができるバイト数の見積もりを返します。次の呼び出しは、同じスレッドまたは別のスレッドである可能性があります。この数のバイトの単一の読み取りまたはスキップはブロックされませんが、より少ないバイトの読み取りまたはスキップが可能です。

これは、現在ストリームにあるバイト数を示すものではありませんが、現在のスレッドをブロックしない実装から読み取られる可能性のあるバイト数の見積もりです。

于 2012-09-03T07:59:28.957 に答える
0

問題は「サーバー/クライアントが接続を閉じた場合」ではありません。問題は、「接続を閉じないのに接続が切断された場合はどうなるか」です。

独自のハートビートプロトコルがなければ、それを検出する方法はありません。

もう1つのオプションは、SO_KEEPALIVEをtrueに設定することです。

「キープアライブオプションがTCPソケットに設定されていて、どちらの方向にも2時間データがソケット間で交換されていない場合(注:実際の値は実装によって異なります)」

私の経験では、2時間ごとよりもはるかに早いです。約5分くらいです。So_KEEPALIVEを使用する以外に、あなたはひどくねじ込まれています:P

私の通信プロトコルでは、2秒ごとに送信される予約済みの「ハートビート」バイトを使用しています。私自身のfilterInputStreamとfilterOutputStreamは、ハートビートバイトを送信/ダイジェストします。

于 2012-09-03T07:55:12.797 に答える