java - BluetoothSocket OutputStream.write() 问题

标签 java android sockets bluetooth

我使用修改后的Google Bluetooth Chat应用程序在两个 Android 设备(Android 5 和 Android 6)之间进行客户端-服务器蓝牙 RFCOMM 通信。

我的客户端应用程序有一些代码:

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写入可用性吗?

附注这种情况与Android 5有关(在Android 6上一切似乎都很正常)。

最佳答案

我不确定这是否有帮助,但尝试分块编写:

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

关于java - BluetoothSocket OutputStream.write() 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41281207/

相关文章:

java - 在项目之间共享 customTags.tld

java - 执行jar文件的服务

sockets - 在 Golang 中限制 tcp 下载速度

android - 如何在 Android 的 React Native webview 中查看本地 HTML 文件?

Android 位置管理器不起作用

sockets - 简单的聊天协议(protocol)

linux - 我怎么知道客户端服务器程序上的主机名

java - 从数组中查找数字的所有索引 (Java)

java - java接口(interface)是如何在内部实现的? (虚拟表?)

android - WifiManager addNetwork 在 Marshmallow 中返回 -1