2013-04-18 81 views
5

有没有人对Exception“Try again”有更多帮助信息?使用LocalServerSocket时出现“IOException:Try again”

输出::

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); 
} 

[尝试/捉等为了清楚起见移除]

我使用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); 

应该是:

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

.read(byte[])不发出声音整个事情一次。我认为这样做是不断sl and和阻塞的。

也有这样的:

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()。这发送最后一个缓冲区。如果你不使用缓冲区,这并不意味着他们不在那里。流以字节发送数据,所以除非你发送一个字节,否则很可能会有一些缓冲区没有被发送,而接收器会得到一半的整数。
  2. 如果您保持流打开,则无法检测流的结束:因此,如果您尝试执行诸如reader.read(buffer)之类的操作时,则会抛出异常,此时buffer的大小超出了发送的数据量。在这种情况下,你必须实现某种prototocle(标题告诉长度或某种结束令牌,知道什么时候该停止阅读)。插座超时,以及断开:
  3. 如果您要发送的消息,并呼吁output.flush()后关闭流,此异常可以通过你meantioned什么引起的。