使用LocalServerSocket时“IOException:再试一次”

时间:2013-04-18 08:36:04

标签: android localserversocket localsocket

是否有人提供有关例外情况的更多有用信息“再试一次”?

我正在使用LocalServerSocketLocalSocket

在应用之间发送位图

输出:

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

[为了清楚起见,删除了尝试/捕获等]

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)

5 个答案:

答案 0 :(得分:4)

您看到的异常可能是与EAGAIN错误等效的java。请参阅示例this answer

您应该处理异常并再次尝试失败的IO操作。

答案 1 :(得分: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[])不会立刻玷污整个事物。我认为这样做会不断地淤塞和阻挡。

还有:

socket.setSoTimeout(60);

arg是毫秒而不是秒,所以应该是:

socket.setSoTimeout(60 * 1000);

我仍然不知道上述严重命名的异常的原因,但希望如果他们知道,有人仍会回答这个问题!

答案 2 :(得分: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;
}

答案 3 :(得分: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;
        }
    }
}

答案 4 :(得分:0)

我知道我迟到了,但我刚解决了同样的问题,有很多事情可以导致这个问题:

  1. 发送时不调用outputStream.flush()。如果你使用作家,那就是writer.flush()。这将发送最后一个缓冲区。如果你不使用缓冲区,那并不意味着它们不存在。流以字节为单位发送数据,因此除非您发送单个字节,否则可能会有一些缓冲区无法发送,并且接收器会获得半个int。
  2. 如果要保持流打开,则无法检测流的结束:因此,如果您尝试执行reader.read(buffer)之类的操作,那么Java会抛出异常,当{的大小时{1}}超过了发送的数据量。在这种情况下,你必须实现某种prototocle(标题告诉长度或某种结束标记,知道何时停止阅读)。
  3. 如果您在发送消息并调用buffer后关闭流,则此异常可能是由您的意思引起的:套接字超时以及断开连接。