Android &引用;IOException:再试一次;使用LocalServerSocket时
有人有关于“重试”异常的更多有用信息吗 我正在使用Android &引用;IOException:再试一次;使用LocalServerSocket时,android,localserversocket,localsocket,Android,Localserversocket,Localsocket,有人有关于“重试”异常的更多有用信息吗 我正在使用LocalServerSocket和LocalSocket在应用程序之间发送位图: 输出: socket = new LocalSocket(); socket.connect(new LocalSocketAddress(SOCKET_NAME)); fos = new DataOutputStream(socket.getOutputStream()); ... public void onEvent() { fos.writeIn
LocalServerSocket
和LocalSocket
在应用程序之间发送位图:
输出:
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等]
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)
因为找不到解决方案,所以我重新设计了这个。但在以不同的方式实现时,我在原始代码中遇到了以下错误:
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);
}
arg的单位是毫秒而不是秒,因此应为:
socket.setSoTimeout(60 * 1000);
我仍然不知道上述名称不正确的异常的原因,尽管如此,如果有人知道,希望他们仍然会回答这个问题您看到的异常可能是与EAGAIN错误相当的java。例如,见
您应该处理异常并再次尝试失败的IO操作。尝试作为流,使用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;
}
private int fill(字节[]缓冲区、int偏移量、int长度)引发IOException{
整数和=0,len;
虽然((sum我认为“重试”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;
}
}
}
我知道我参加聚会迟到了,但我刚刚解决了同一个问题,有很多事情可能导致这种情况:
发送时不调用outputStream.flush()
。如果使用writer,则为writer.flush()
。这将发送最后一个缓冲区。如果不使用缓冲区,并不意味着它们不存在。流式传输以字节为单位发送数据,因此,除非您发送单个字节,否则很可能有一些缓冲区未被发送,而接收者得到半个整数
如果您保持流开放,则无法检测流的结束:因此,如果您尝试执行reader.read(buffer)
,当缓冲区的大小超过发送的数据量时,Java将抛出异常。在这种情况下,您必须实现某种协议(标题告诉长度或某种结束标记,以知道何时停止读取)
如果您在发送消息并调用output.flush()
后关闭流,则此异常可能由您的意思引起:套接字超时以及断开连接
它引发了一个特定的阻塞操作。看起来上面的答案不适用。嗯,无论如何,它不应该适用。啊,我明白了。这是LocalSocketImpl中的一个错误吗?如果您将错误视为EAGAIN并重试,会发生什么?
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;
}
}
}