Java BluetoothSocket OutputStream.write()问题
我使用修改后的应用程序在两个安卓设备(安卓5和安卓6)之间进行客户机-服务器蓝牙RFCOMM通信 我的客户端应用程序有一些代码: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
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 WM或PORT\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 WM或PORT\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代码中的常量。但它取决于硬件、制造商和安卓版本。它可以完美地处理小数据。但是我仍然不能发送大字节数组(溢出最终仍然存在),它可以很好地处理小数据。但我仍然无法发送大字节数组(溢出最终仍然存在)。