2011-11-11 19 views
5

Sto provando a trasferire circa un megabyte di dati arbitrari alla volta da un telefono Android a un altro. Attualmente, scrivo le dimensioni, un codice di comando e i dati su un DataOutputStream attorno a un BufferedOutputStream, attorno allo OutputStream restituito da bluetoothSocketInstance.getOutputStream().Trasferimento di grandi quantità di dati tramite Bluetooth su Android Gingerbread

Il telefono ricevente legge la dimensione e il codice di comando e quindi legge dal flusso di input finché non ha ottenuto tutti i dati che si aspetta. Funziona per stringhe brevi, ma per i file più grandi non tutti i dati vengono trasferiti. L'esecuzione dell'app nel debugger mostra che la scrittura ritorna senza eccezioni e la lettura legge una frazione dei byte attesi e quindi blocca indefinitamente. Inoltre non getta alcuna eccezione.

C'è un buffer da qualche parte che si sta riempiendo? C'è qualcos'altro che devo fare per garantire che tutti i dati vengano trasferiti?

Il mio codice per il mittente e il destinatario sono al di sotto:

mittente:

try { 

      DataOutputStream d = new DataOutputStream(new BufferedOutputStream(mmOutStream,buffer.length+8)); 
      //int b= buffer.length; 
      d.writeInt(buffer.length); 
      d.writeInt(command); 

      d.write(buffer); 
      d.flush(); 

     } catch (IOException e) { 
      Log.e(TAG, "Exception during write", e); 
     } 
    } 

Ricevitore:

try { 

       // Read from the InputStream 
       int messageSize= inStream.readInt(); 
       int messageCode = inStream.readInt(); 
       bytes=0; 
       buffer =new byte[messageSize]; 
       while(bytes < messageSize) 
       { 
        bytes += inStream.read(buffer,bytes,messageSize - bytes); 

       } 
        message = bytes; 
      } catch (IOException e) { 
       Log.e(TAG, "disconnected", e); 
       connectionLost(); 
       break; 
      } 

risposta

3

Dopo un po 'di test da parte mia, ho cambiato il mio codice invio a assomiglia a questo:

for(int i=0; i<buffer.length;i+=BIG_NUM) 
      { 
       int b = ((i+BIG_NUM) < buffer.length) ? BIG_NUM: buffer.length - i; 
       d.write(buffer,i,b); 
       d.flush(); 
      } 

I file ora vengono inviati. Qualcuno ha un'idea del perché? La chiamata al blocco flush() fino a quando i dati non sono stati effettivamente trasferiti? C'è qualche documentazione sulla dimensione dei buffer di invio e ricezione che mi aiuterebbe a decidere quanto grande posso fare in modo sicuro BIG_NUM?

+0

Il buffer di invio Bluetooth è 70 KiB nel codice nativo di BluetoothSocket (nella mia copia). Inoltre, Linux lo raddoppia internamente (a causa delle "strutture dati del kernel"). Tuttavia, questo non dovrebbe essere un problema poiché 'write (3)' dovrebbe gestirlo. Inoltre, flush non può fare nulla (perché la scrittura sembra essere sincrona) e (flush) non viene sovrascritta. – yingted

0

Ho un problema simile, quando invio file ci sono alcune parti mancanti. Provo BufferedOutputStream ma il problema esiste ancora.

Finalmente trovo soluzione semplice:

Non è necessario inviare la lunghezza del buffer, basta dividere l'invio di buffer per array di byte (ad esempio [8192]) e in ricezione lato fare in modo che questo buffer è molto più grande circa 4 o 8 volte rispetto all'invio del buffer. Questo ha funzionato per me e il file è stato inviato completato.

+0

È simile a come ho risolto il problema. Sai quale può essere la dimensione massima del buffer di invio prima di dividerlo? – ethan

Problemi correlati