2013-04-18 7 views
5

У кого-нибудь есть более полезная информация об исключении «Попробуйте еще раз»?«IOException: попробуйте еще раз» при использовании LocalServerSocket

Я посылаю Bitmaps между приложениями с помощью 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); 
} 

[попробовать/поймать и т.д. удалены для ясности]

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[]) не чавкать все это сразу. Я предполагал, что это постоянно прерывается и блокируется, пока он это делает.

Существует также следующее:

socket.setSoTimeout(60); 

агд в Millis, а не секунд, так что должно быть:

socket.setSoTimeout(60 * 1000); 

Я до сих пор не знаю причину выше плохо имени исключения хотя, надеюсь, кто-то все равно ответит на это, если они знают!

4

Исключение, которое вы видите, вероятно, эквивалентно java ошибке EAGAIN. См., Например, this answer.

Вы должны обработать исключение и повторить попытку неудачной операции ввода-вывода.

+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(). Это отправляет последний буфер. Если вы не используете буферы, это не значит, что их нет. Поток отправляет данные в байтах, поэтому, если вы не отправляете один байт, скорее всего, есть какой-то буфер по линии, которая не отправляется, а получатель получает половину int.
  2. Если вы не открываете потоки, невозможно определить конец потока: поэтому Java будет вызывать исключение, если вы попытаетесь сделать что-то вроде reader.read(buffer), когда размер buffer превышает количество отправленных данных. В этом случае вы должны реализовать некоторый прототип (заголовок, указывающий длину или какой-либо конечный токен, чтобы знать, когда прекратить чтение).
  3. Если вы закрываете потоки после отправки сообщения и вызывают output.flush(), это исключение может быть вызвано тем, что вы имели в виду: тайм-ауты сокетов, а также разъединения.
Смежные вопросы