Android + Bluetooth (Bluecove) - необходимо закрыть OutputStream для фактической записи данных
У меня устройство Android выступает в роли клиента, ПК - это сервер Bluetooth, использующий библиотеку Bluecove.
Фрагмент кода от клиента:
btSocket = serverBt.createRfcommSocketToServiceRecord(myUuid);
btAdapter.cancelDiscovery();
btSocket.connect();
InputStream in = btSocket.getInputStream();
OutputStream out = btSocket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out);
InputStreamReader isr = new InputStreamReader(in);
osw.write(55);
osw.flush();
out.flush();
//osw.close();
logTheEvent("Stuff got written, now waiting for the response.");
int dummy = isr.read();
logTheEvent("Servers response: "+ new Integer(dummy).toString());
И сервер:
StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier)Connector.open( connectionString, Connector.READ_WRITE );
StreamConnection incomingConnection=streamConnNotifier.acceptAndOpen();
InputStream in = incomingConnection.openInputStream();
OutputStream out = incomingConnection.openOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out);
InputStreamReader isr = new InputStreamReader(in);
int fromClient = isr.read();
System.out.println("Got from client " + new Integer(fromClient).toString());
osw.write(999);
Когда osw.close(); при незакомментированном клиенте сообщение передается на сервер, однако клиент не может получить ответ, генерируется исключение IOException с сообщением "сокет уже закрыт". Однако, когда osw.close(); комментируется, как клиент, так и сервер зависают: A. Клиент зависает при чтении ответа сервера, конечно, B. Сервер зависает в streamConnNotifier.acceptAndOpen();
Что нужно сделать, чтобы обеспечить двустороннюю связь? Виноват ли мой код, или компьютерный стек Bluetoototh, или bluecove?
1 ответ
Bluetooth использует буферный выход. Это означает, что есть небольшая область памяти, которая содержит все данные, которые вы записываете в поток. Когда эта ячейка памяти заполняется, она записывает данные буфера в сокет в пакете. Когда вы преждевременно закрываете сокет, этот буфер стирается, а данные исчезают.
Чтобы заставить поток писать, попробуйте вызвать flush()
Еще можно сделать размер буфера очень маленьким, чтобы данные всегда записывались. Однако, если вы сделаете это, производительность будет не очень хорошей.
К сожалению, у меня нет всего кода, который я написал, но здесь есть базовый проект