2011-11-11 15 views
5

Estoy tratando de transferir aproximadamente un megabyte de datos arbitrarios a la vez desde un teléfono Android a otro. Actualmente, escribo el tamaño, un código de comando y los datos en un DataOutputStream alrededor de un BufferedOutputStream, alrededor del OutputStream devuelto desde bluetoothSocketInstance.getOutputStream().Transferencia de grandes cantidades de datos a través de bluetooth en Android Gingerbread

El teléfono receptor lee el tamaño y el código de comando y luego lee desde el flujo de entrada hasta que haya obtenido todos los datos que está esperando. Esto funciona para cadenas cortas, pero para archivos más grandes no se transfieren todos los datos. Ejecutar la aplicación en el depurador muestra que la escritura regresa sin excepciones y la lectura lee una fracción de los bytes esperados y luego bloquea indefinidamente. Tampoco arroja ninguna excepción.

¿Hay un búfer en algún lugar que se está llenando? ¿Hay algo más que deba hacer para asegurarme de que se transfieren todos los datos?

Mi código para el emisor y el receptor están por debajo:

remitente:

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

receptor:

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

Respuesta

3

Después de algunas pruebas más en mi final, he cambiado mi código de enviar a mira esto:

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

Los archivos ahora se envían. ¿Alguien tiene una idea de por qué? ¿La llamada al bloque flush() se bloquea hasta que los datos se hayan transferido realmente? ¿Hay alguna documentación sobre el tamaño de los buffers de envío y recepción que me ayuden a decidir qué tan grande puedo hacer de manera segura BIG_NUM?

+0

El buffer de envío de bluetooth es de 70 KiB en el código nativo de BluetoothSocket (en mi copia). Además, Linux duplica esto internamente (debido a las "estructuras de datos del kernel"). Sin embargo, esto no debería ser un problema ya que 'write (3)' debería gestionar esto. Además, el enjuague puede no hacer nada (porque la escritura parece ser sincrónica) y no se sobrescribe (al ras). – yingted

0

Tengo un problema similar, al enviar el archivo faltan algunas partes. Intento BufferedOutputStream pero el problema todavía existe.

fin encuentro solución simple:

No es necesario enviar magnitud de la memoria, simplemente divide el envío de búfer de matriz de bytes (por ejemplo, [8192]) y el lado recepción asegurarse de que este buffer es mucho más grande aproximadamente 4 u 8 veces más que enviar buffer. Esto funcionó para mí y el archivo se envió completo.

+0

Eso es similar a cómo terminé resolviendo el problema. ¿Sabes cuál es el tamaño máximo del buffer de envío antes de dividirlo? – ethan

Cuestiones relacionadas