2016-12-22 60 views
1

我使用修改Google Bluetooth Chat繼續申請2個Android設備(與Android 5和Android 6)之間的客戶機 - 服務器藍牙RFCOMM通信。的BluetoothSocket OutputStream.write()問題

還有就是我的客戶端應用程序的一些代碼:

private class ConnectedThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final BufferedInputStream mmInStream; 
    private final BufferedOutputStream mmOutStream; 

    private ByteBuffer outputBuffer = null; 

    private int currentOperation = 0; 

    private byte currentMessageType = 0; 

    ConnectedThread(BluetoothSocket socket) { 
     Log.d(LOG_TAG, "create ConnectedThread: Insecure"); 
     mmSocket = socket; 
     BufferedInputStream tmpIn = null; 
     BufferedOutputStream tmpOut = null; 

     try { 
      tmpIn = new BufferedInputStream(socket.getInputStream()); 
      tmpOut = new BufferedOutputStream(socket.getOutputStream()); 
     } catch (IOException e) { 
      Log.e(LOG_TAG, "temp sockets not created", e); 
     } 

     mmInStream = tmpIn; 
     mmOutStream = tmpOut; 
     setState(STATE_CONNECTED); 
    } 
    public void run() { 
     Log.i(LOG_TAG, "BEGIN mConnectedThread"); 
     byte[] buffer; 
     ByteBuffer intBuf; 
     int tempInt; 

     while (mState == STATE_CONNECTED) { 
      try { 
       if(mmInStream.available()>8) { 
        Log.i(LOG_TAG, mmInStream.available() + " f"); 
        buffer = new byte[9]; 
        mmInStream.read(buffer, 0, 9); 

        intBuf = ByteBuffer.wrap(buffer); 
        Log.i(LOG_TAG, "NEW MESSAGE: "+intBuf.getInt()+" "+intBuf.get()+" "+intBuf.getInt()); 
        intBuf.rewind(); 

        tempInt = intBuf.getInt(); 
        Log.i(LOG_TAG, tempInt + " GET OP ID " + intBuf.capacity()); 

        currentMessageType = intBuf.get(); 
        Log.i(LOG_TAG, currentMessageType + " GET OP TYPE"); 

        // ... some more code 
       } 
      } 
      catch (IOException err) { 
       Log.e(LOG_TAG, "disconnected", err); 
       connectionLost(); 
       break; 
      } 
     } 
    } 
    void write(byte[] data) { 
     try { 
      Log.i(LOG_TAG, "WRITE NEW MESSAGE: "+data.length); 

      mmOutStream.write(data); 
      SystemClock.sleep(200); 

     } catch (IOException e) { 
      Log.e(LOG_TAG, "Exception during write", e); 
     } 
    } 
    void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(LOG_TAG, "close() of connect socket failed", e); 
     } 
    } 

這部分管理的BluetoothSocket讀/寫操作。

那麼問題是什麼?當我發送數據大小爲< 10000字節(字節數組)它一切正常。但後來我嘗試發送一些大尺寸的數據(> 10000字節),並收到此消息(與logcat的):

12-22 12:53:49.849 28177-28177/com.lukanin.testappjava2 I/(BLUETOOTH): DATA LENGTH: 35722 OPT ID: 1 TYPE: 11 
12-22 12:53:49.849 28177-28177/com.lukanin.testappjava2 I/(BLUETOOTH): SEND DATA: 1 11 35722 
12-22 12:53:49.849 28177-28177/com.lukanin.testappjava2 I/(BLUETOOTH): WRITE NEW MESSAGE: 35731 

[ 12-22 12:53:49.849 21464:21536 D/   ] 
PORT_WriteDataCO: tx queue is full,tx.queue_size:10890,tx.queue.count:11,available:14941 

[ 12-22 12:53:49.959 21464:21536 D/   ] 
PORT_WriteDataCO: tx queue is full,tx.queue_size:10890,tx.queue.count:11,available:3061 

我覺得有某種OutputStream的溢出,但我不明白如何解決它。我應該怎麼做才能防止這種情況發生?是否有任何方法來檢查OutputStream寫入可用性?

P.S.這種情況是相關的Android 5(在Android 6上似乎都是正常的)。

+0

我不理解的問題到底是什麼,但看是否添加mmOutStream。寫入數據後flush()有幫助。 – pringi

+0

通過你寫的logcat示例,我無法察覺到這個問題。你能解釋得更好嗎? – pringi

+0

沒有。我試過這種解決方案。在這種情況下,我只接收** PORT_WriteDataCO中的一個:tx隊列已滿... **錯誤。 – trinarr

回答

0

我不知道這是否會幫助,但嘗試塊寫:

private static funal int CHUNK_SIZE = 200; 

..... 

int currentIndex = 0; 
int size = data.length; 
while (currentIndex < size) { 
    int currentLength = Math.Min(size-currentIndex, CHUNK_SIZE); 
    memOutStream.write(data, currentIndex, currentLength); 
    currentIndex += currentLength; 
} 
+0

它適用於小數據。但我仍然無法發送大字節數組(溢出最終仍然存在)。 – trinarr

0

在Android中5,

/* if we're over buffer high water mark, we're done */ 
     if ((p_port->tx.queue_size > PORT_TX_HIGH_WM) 
     || (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM)) 
     { 
      port_flow_control_user(p_port); 
      event |= PORT_EV_FC; 
      debug("tx queue is full,tx.queue_size:%d,tx.queue.count:%d,available:%d", 
        p_port->tx.queue_size, p_port->tx.queue.count, available); 
      break; 
     } 

我不知道該值PORT_TX_HIGH_WMPORT_TX_BUF_HIGH_WM但假設這tx.queue_size比你更可發送最大。

https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/android-5.0.0_r3/stack/rfcomm/port_api.c

+0

謝謝你的信息。也許你知道是否有可能接收當前可寫的tx隊列的容量? – trinarr

+0

在Android中我不知道。只有發現這篇文章解釋MTU是如何探索,但是這是非常低的水平:http://blog.csdn.net/wendell_gong/article/details/45060337 – pringi

+0

我已經發現PORT_TX_BUF_HIGH_WM = 4,但PORT_TX_HIGH_WM是計算複雜,但不應該大於1691.這是Android代碼中的常量。但這取決於硬件,製造商和Android版本。 – pringi

相關問題