2011-11-11 140 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