2016-07-22 2 views
4

ここにはクライアント/サーバーのフローがあります。閉じた出力ストリームへのJavaの書き込みでioexceptionをスローしない

ソケットはメインスレッドで作成されます。

  1. ソケットは1
  2. クライアントが
  3. サーバーがクライアントに応答し、サーバにデータを送信するスレッドに渡し
  4. Serverは、ソケットがメインに戻っclose()
  5. 起動することにより、入力ストリーム、出力ストリーム、およびソケットをクローズスレッド2に渡されます。
  6. クライアントはサーバにデータを書き込みます - 例外もエラーもなく、サーバはデータを取得しません
  7. クライアントのデータ読み取り試行 - 例外なし、エラーなし

ソケットが閉じられた問題を検出するにはどうすればよいですか?

try { 
     os = new DataOutputStream(this.socket.getOutputStream()); 
     os.write(data); 
     os.flush(); 
     System.out.println("Written " + data.length + " bytes"); 
    } catch (IOException e) { 
     System.out.println("Client failed to write to stream"); 
     System.out.println(e.getMessage()); 
     e.printStackTrace(); 
    } 

例外はスローされません。それはWritten 60 bytesと言います。何か案は?


ここでUPDATE

は私が応答を読む方法です。私はデータを待って、最初の4バイト(応答の長さを与える)を読み取り、指定された長さを読むまで読み取りを続けます。このループはデータが一度も来ないので終了しません。

is = new DataInputStream(this.socket.getInputStream()); 
    while(true){ 
     while(is.available() > 0){ 
      bos.write(is.read()); 
     } 
     if(contentLength == 0 && bos.size() > 3){ 
      byte[] bytes = bos.toByteArray(); 
      byte[] size = Arrays.copyOf(bytes, 4); 
      contentLength = ByteBuffer.wrap(size).getInt(); 
     } 
     if(bos.size() - 4 < contentLength){ 
      continue; 
     } 
     break; 
    } 
+0

あなたはSocketExceptionをチェックしましたか?あなたがすべてを閉じているなら、それもそれを投げ捨てるべきです。 –

+0

はい、例外はスローされません。スレッド間で渡されるソケットに関する追加情報で質問を更新しました –

+1

ブロックされていない閉じたストリームから何バイト読み込めますか?なし。したがって、 'available()'はゼロを返さなければなりません。 – erickson

答えて

1

これは60バイトを書きました。サーバーはもう聞きません。何かがあるかどうかを確認するために入力ストリームを取得する必要があります。何も戻ってこない場合は、接続がうまくいかないことがわかります。

UPDATE

サーバーが応答しているかどうかを判断するためにタイマーを使用してください。

Long currenttime = System.currentTimeMillis(); 
while(System.currentTimeMillis() - currentTime < x){ //x = miliseconds you want to wait 
    (try to read from server) 
} 

それがx秒よりも長くかかる場合は、この方法で、それがタイムアウトになると、サーバーは、TCPコネクションの終わりを閉じたときあなたは、whileループ

+0

私は参照してください。私はデータを読み取る方法で私の質問を更新するつもりです、それはここでの犯人かもしれません。 –

+1

ソケットの読み取りタイムアウトについて聞いたことがありませんか? – EJP

1

後引くいくつかのエラーを行うことができ、それが送信しますFINパケットを送信してクライアントに伝えます。クライアントプログラムはこれを、InputStreamが最後に到達するのと見なします。また、クライアントがサーバーに書き込もうとすると、RSTパケットがシグナルエラーに送信されます。 RSTが受信された後にクライアントプログラムが書き込みを試みると、APIはSocketExceptionをスローし、 "connection reset"というメッセージを出します。

あなたの問題は、ここで入力の終わりを検出すると次のとおりです。

while(is.available() > 0){ 
     bos.write(is.read()); 
    } 

available方法は、おそらくあなたはそれがないと思う何をしません。 4バイトを読み取る場合は、4バイトを読み取ります。

byte[] bytes = new byte[4]; 
is.readFully(bytes); // throws EOFException on end of input 
関連する問題