2013-04-18 17 views
5

「再試行」に関する例外的な情報がありますか?LocalServerSocketの使用中に「IOException:再試行」

出力:

socket = new LocalSocket(); 
socket.connect(new LocalSocketAddress(SOCKET_NAME)); 
fos = new DataOutputStream(socket.getOutputStream()); 
... 

public void onEvent() { 
    fos.writeInt(width); 
    fos.writeInt(height); 
    fos.writeInt(newBuffer.length); 
    fos.write(newBuffer); 
} 

入力:

server = new LocalServerSocket(SOCKET_NAME); 
socket = server.accept(); 
socket.setSoTimeout(60); 

while(true) { 

    int width = fis.readInt(); // IO Exception being thrown here 
    int height = fis.readInt(); 
    int length = fis.readInt(); 
    byte[] bytes = new byte[length]; 
    fis.read(bytes); 
} 

[のtry/catchなどを明確にするため削除]

私はLocalServerSocketLocalSocketを使用してアプリケーション間でビットマップを送信しています

04-18 09:19:11.664: W/System.err(1268): java.io.IOException: Try again 
04-18 09:19:11.664: W/System.err(1268):  at android.net.LocalSocketImpl.readba_native(Native Method) 
04-18 09:19:11.664: W/System.err(1268):  at android.net.LocalSocketImpl.access$400(LocalSocketImpl.java:29) 
04-18 09:19:11.664: W/System.err(1268):  at android.net.LocalSocketImpl$SocketInputStream.read(LocalSocketImpl.java:92) 
04-18 09:19:11.664: W/System.err(1268):  at libcore.io.Streams.readFully(Streams.java:81) 
04-18 09:19:11.664: W/System.err(1268):  at java.io.DataInputStream.readInt(DataInputStream.java:124) 
04-18 09:19:11.664: W/System.err(1268):  at com.test.util.BitmapSendingUtils$BitmapReceiver$1.run(BitmapSendingUtils.java:105) 

答えて

3

私は解決策を見つけることができなかったので、これを再設計しました。それを別の方法を実装しながら、しかし、私は元のコードでこれらのエラーに出くわした:

byte[] bytes = new byte[length]; 
fis.read(bytes); 

は次のようになります。.read(byte[])として

byte[] content = new byte[length]; 
int read = is.read(content); 
while(read < content.length) { 
    read += is.read(content, read, content.length - read); 
} 

が一度に全部を読まれません。私は、これがそうしている間、これが絶え間なく荒れ切ってブロックされたと仮定しました。

これもあります:

socket.setSoTimeout(60); 

argはむしろ秒よりもミリ秒であるので、次のようになります。

socket.setSoTimeout(60 * 1000); 

私はまだ上記ひどくという名前の例外の原因を知りませんしかし、うまくいけば、誰かが知っていれば、まだこれに答えるだろうが!

4

例外は、おそらくEAGAINエラーに相当するJavaです。例えばthis answerを参照してください。

例外を処理して、失敗したIO操作を再度試みる必要があります。

+0

特定のブロッキング操作をスローします。上記の答えが当てはまるようには見えません。まあ、それはとにかくはいけません。 – Graeme

+0

ああ、そうだ。 LocalSocketImplのバグですか?エラーをEAGAINとして扱い、もう一度やり直すとどうなりますか? –

+0

この問題をどのように解決したか教えてください –

0

流れとして試みは、制御するかどうかのフローを終了するmInputValidを使用します。

private int fill(byte[] buffer, int offset,int length) throws IOException { 
    int sum = 0, len; 
    while ((sum<length) && mInputValid) { 
     try{ 
      len = is.read(buffer, offset + sum, length - sum); 
      if (len < 0) { 
       throw new IOException("End of stream"); 
      } else{ 
       sum += len; 
       Log.i(TAG, "is.read: " + len + " buffer:" + buffer[0]); 
      } 
     } 
     catch (IOException e){ 
      e.printStackTrace(); 
      Log.i(TAG, "read input fail, try again"); 
      continue; 
     } 
    } 
    return sum; 
} 
0

私は「もう一度お試しください」にIOExceptionが実際にしてSocketTimeoutExceptionが処理されるのと同じ方法で扱われるべきだと思います。これは非常に悪い実装APIですが、私たちは、Android上で、このような安っぽいデザインに使用されます。

private int read(byte[] buffer) throws IOException { 

    while (true) { 
     try { 
      return fis.read(buffer); 
     } catch (SocketTimeoutException e) { 
      continue; 
     } catch (IOException e) { 
      String message = e.getMessage(); 
      if (message != null && message.equals("Try again")) { 
       continue; 
      } 
      throw e; 
     } 
    } 
} 

private int readInt() throws IOException { 
    while (true) { 
     try { 
      return fis.readInt(); 
     } catch (SocketTimeoutException e) { 
      continue; 
     } catch (IOException e) { 
      String message = e.getMessage(); 
      if (message != null && message.equals("Try again")) { 
       continue; 
      } 
      throw e; 
     } 
    } 
} 
0

私はパーティーに遅れていますけど、私はちょうど同じ問題を解決し、その多くのものがありますこれを引き起こす可能性があります:

  1. 送信時にoutputStream.flush()を呼び出していません。ライターを使用している場合は、writer.flush()です。最後のバッファが送信されます。バッファを使用していない場合、バッファが存在しないことを意味するわけではありません。ストリームはバイト単位でデータを送信するので、1バイトを送信しない限り、送信されない行の下にバッファがあり、受信者がintの半分を取得する可能性があります。
  2. ストリームを開いたままにしておくと、ストリームの終わりを検出する方法がないため、bufferのサイズが送信されたデータ量を超えると、reader.read(buffer)などの操作を実行しようとすると例外がスローされます。この場合、prototocle(ヘッダの長さや何らかのエンドトークンを知らせるヘッダ)を実装して、いつ読み込みを停止するかを知る必要があります。
  3. メッセージを送信してストリームを終了し、output.flush()を呼び出す場合、この例外は、あなたが意図したもの、つまりソケットタイムアウトと切断のために発生する可能性があります。
関連する問題