Java BluetoothSocket OutputStream.write()问题

Java BluetoothSocket OutputStream.write()问题,java,android,sockets,bluetooth,Java,Android,Sockets,Bluetooth,我使用修改后的应用程序在两个安卓设备(安卓5和安卓6)之间进行客户机-服务器蓝牙RFCOMM通信 我的客户端应用程序有一些代码: private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final BufferedInputStream mmInStream; private final BufferedOutputStream mmOut

我使用修改后的应用程序在两个安卓设备(安卓5和安卓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字节的数据并收到此消息(使用LogCat)时:

我认为存在某种OutputStream溢出,但我不知道如何修复它。我应该怎么做来防止这种情况?是否有任何方法检查OutputStream写入可用性

另外,这种情况与安卓5相关(安卓6上的一切似乎都很正常)。

安卓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\u TX\u HIGH\u WMPORT\u TX\u BUF\u HIGH\u WM的值,但假设此TX.queue\u大小大于您可以发送的最大值

请参见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\u TX\u HIGH\u WMPORT\u TX\u BUF\u HIGH\u WM的值,但假设此TX.queue\u大小大于您可以发送的最大值


请参见

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

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; 
}
private static funal int CHUNK_SIZE=200;
.....
int currentIndex=0;
int size=data.length;
while(当前索引<大小){
int currentLength=Math.Min(大小currentIndex,块大小);
memOutStream.write(数据、当前索引、当前长度);
currentIndex+=当前长度;
}

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

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; 
}
private static funal int CHUNK_SIZE=200;
.....
int currentIndex=0;
int size=data.length;
while(当前索引<大小){
int currentLength=Math.Min(大小currentIndex,块大小);
memOutStream.write(数据、当前索引、当前长度);
currentIndex+=当前长度;
}


我不清楚问题到底是什么,但看看在写入数据后添加mmOutStream.flush()是否有帮助。根据您编写的logcat示例,我看不出问题所在。你能解释清楚吗?不。我试过这样的解决办法。在这种情况下,我只收到一个端口_writedacco:tx队列已满。。。错误。不确定,但tx.queue_大小仅为10890。如果您发送更多,它将溢出。我找到了一些有关它的信息:。无论如何,是否有可能接收到tx队列的可写容量?我不知道问题到底是什么,但看看在写入数据后添加mmOutStream.flush()是否有帮助。根据您编写的logcat示例,我无法察觉问题。你能解释清楚吗?不。我试过这样的解决办法。在这种情况下,我只收到一个端口_writedacco:tx队列已满。。。错误。不确定,但tx.queue_大小仅为10890。如果您发送更多,它将溢出。我找到了一些有关它的信息:。无论如何,是否有可能接收到tx队列的可写容量?谢谢您提供的信息。也许你知道有没有可能收到tx队列当前的可写容量?在Android中我不知道。只发现这篇文章解释了MTU是如何发现的,但这是非常低级的:我发现PORT_TX_BUF_HIGH_WM=4,但PORT_TX_HIGH_WM的计算比较复杂,但它不应该大于1691。这是Android代码中的常量。但这取决于硬件、制造商和Android版本。谢谢您提供的信息。也许你知道有没有可能收到tx队列当前的可写容量?在Android中我不知道。只发现这篇文章解释了MTU是如何发现的,但这是非常低级的:我发现PORT_TX_BUF_HIGH_WM=4,但PORT_TX_HIGH_WM的计算比较复杂,但它不应该大于1691。这是Android代码中的常量。但它取决于硬件、制造商和安卓版本。它可以完美地处理小数据。但是我仍然不能发送大字节数组(溢出最终仍然存在),它可以很好地处理小数据。但我仍然无法发送大字节数组(溢出最终仍然存在)。