2011-11-11 56 views
5

传输大量数据的蓝牙我试图在同一时间从一个Android手机传送有关的任意数据的兆字节到另一个。目前,我写的大小,指令代码和数据的DataOutputStream一个BufferedOutputStream前后,左右从bluetoothSocketInstance.getOutputStream()返回OutputStream在Android姜饼

接收电话读取大小和命令代码,然后从输入流中读取,直到它已经得到了所有它期待的数据。这适用于短字符串,但对于较大的文件,并非所有数据都被传输。在调试器中运行应用程序表明写入没有任何异常,读取读取预期字节的一小部分,然后无限期地阻止。它也不会抛出任何例外。

是否有一个缓冲的地方,要填满?我还需要做些什么来确保所有数据都被传输?

我对发送者和接收者代码低于:

发件人:

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

接收机:

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

回答

3

在我结束一些测试后,我改变了我的发码是这样的:

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

现在发送文件。有没有人有一个想法,为什么?阻止flush()的呼叫,直到数据实际传输完成。是否有任何有关发送和接收缓冲区大小的文档,这些文档可以帮助我确定可以安全地生成多大的文件数BIG_NUM

+0

BluetoothSocket本机代码中的蓝牙发送缓冲区为70 KiB(在我的副本中)。而且,Linux在内部使其翻倍(因为“内核数据结构”)。然而,这不应该成为一个问题,因为'write(3)'应该管理这个。而且,flush可能什么都不做(因为写入似乎是同步的),并且它(flush)不会被覆盖。 – yingted

0

我有类似的问题,发送文件时,也有一些零件丢失。我尝试BufferedOutputStream,但问题仍然存在。

最后我找到简单的解决办法:

你并不需要发送缓冲区长度,只是拆分发送缓冲区的字节数组(例如[8192])和接收方确保此缓冲区更大比发送缓冲大约4或8倍。这对我有用,文件发送完成。

+0

这与我最终解决问题的方式类似。在分割之前,你知道发送缓冲区的最大大小是多少? – ethan