简体   繁体   English

BluetoothSocket OutputStream.write()问题

[英]BluetoothSocket OutputStream.write() issue

I use modified Google Bluetooth Chat application to proceed client-server Bluetooth RFCOMM communication between two Android devices (with Android 5 and Android 6). 我使用改进的Google蓝牙聊天应用程序在两个Android设备(Android 5和Android 6)之间进行客户端 - 服务器蓝牙RFCOMM通信。

There is some code of my client application: 我的客户端应用程序有一些代码:

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

This part manages the BluetoothSocket read/write operations. 该部分管理BluetoothSocket读/写操作。

So what's the problem? 所以有什么问题? When I send data with size <10000 bytes (byte array) it all goes normally. 当我发送大小<10000字节 (字节数组)的数据时,一切正常。 But then I try to send some big-sized data ( >10000 bytes ) and recieve this message (with LogCat): 但后来我尝试发送一些大型数据( > 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

I think there is some kind of OutputStream overflow, but I can't understand how to fix it. 我认为有一些OutputStream溢出,但我无法理解如何修复它。 What should I do to prevent such situation? 我该怎么做才能防止这种情况发生? Is there any methods to check the OutputStream write availability? 有没有方法可以检查OutputStream写入的可用性?

PS This situation is relevant for Android 5 (on Android 6 all seems to be normal). PS这种情况与Android 5相关(在Android 6上似乎都很正常)。

In Android 5, 在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;
         }

I don't know the values for PORT_TX_HIGH_WM or PORT_TX_BUF_HIGH_WM but assume that this tx.queue_size is more than the maximum you can send. 我不知道PORT_TX_HIGH_WMPORT_TX_BUF_HIGH_WM的值,但假设此tx.queue_size超过您可以发送的最大值。

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

I am not sure whether this will help, but try to write in chunks: 我不确定这是否会有所帮助,但我会尝试写下块:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM