Данные Bluetooth разделяются на устройстве Android - PullRequest
1 голос
/ 26 января 2012

Я отправляю данные с одного устройства на другое (Samsung Tab и Sony Xperia). Все в порядке, пока я не достигну длины 994 байта. В этот момент он разбивает его на 2 сообщения по 990 и 4 байта. Так что, конечно, десериализация не удалась. Я не уверен, происходит ли разделение на стороне отправителя или на стороне получателя.

Почему это? Существует ли максимум, который он может отправить за один раз?

Если так, как я могу собрать это вместе? Если бы я знал, что 990 - это фиксированное число, то я мог бы легко сделать это, комбинируя их, но меняется ли оно от устройства к устройству?

Я даю ему буфер для 2000 байтов, чтобы в нем было достаточно места.

Я использую код из примера Bluetooth.

=============================================== =======================

Согласно TJD ниже:

В данный момент я отправляю такой объект:

открытый класс BTMessage реализует Serializable {

/**
 * 
 */
private static final long serialVersionUID = -2037775782014806765L;
public int what;
public Object objectToSend;
public int playerId;
public int currentPlayerId;
public BTMessage(int what, int playerId, int currentPlayerId, Object objectToSend){
    this.what = what;
    this.playerId = playerId;
    this.currentPlayerId = playerId;
    this.objectToSend = objectToSend;
}

objectToSend - это сериализуемый объект.

Затем я сериализирую его в байтовый массив и отправляю.

BTMessage btMessage = new BTMessage(what,playerId,currentPlayerId,objectToWrite);
write(toByteArray(btMessage));

На другом конце я переворачиваю процедуру.

Проблема заключается в том, что добавление длины не всегда помогает, поскольку при десериализации полученного сообщения также требуется десериализация «objectToSend». Так как сообщение неполное, я все равно сталкиваюсь с той же проблемой.

Единственное, о чем я могу думать, это изменить его на:

public class BTMessage implements Serializable {
/**
 * 
 */
private static final long serialVersionUID = -2037775782014806765L;
    public int len;
public int what;
public byte[] objectToSend;
public int playerId;
public int currentPlayerId;
public BTMessage(int len, int what, int playerId, int currentPlayerId, byte[] objectToSend){
            this.len = len;
    this.what = what;
    this.playerId = playerId;
    this.currentPlayerId = playerId;
    this.objectToSend = objectToSend;
}

Тогда я бы выполнил сериализацию в 2 этапа. Сначала я бы сериализовал объект, который хочу отправить, в байтовый массив. Затем я бы создавал экземпляр «BTMessage», передавая массив байтов, созданный из сериализации как «objectToSend», и затем сериализовывал его. Выше теперь будет:

byte[] message = toByteArray(objectToWrite);
BTMessage btMessage = new BTMessage(message.length,what,playerId,currentPlayerId,message);
write(toByteArray(btMessage));

На другом конце я бы десериализовал полученное сообщение. Затем я проверил бы длину и произвел бы еще одно чтение, пока не получу полную длину Только тогда я могу десериализовать весь отправленный объект (objectToSend).

Это путь?

1 Ответ

4 голосов
/ 27 января 2012

Используете ли вы RFCOMM для отправки данных?Если это так, то вы не можете полагаться на какие-либо предположения о размере пакета.Абстракция RFCOMM похожа на последовательный порт, где вы просто отправляете потоки байтов.В данных RFCOMM отсутствует понятие пакетов.

Вы можете обнаружить, что естественно небольшие пакеты обычно объединяются, но размер сегментации по воздуху всегда будет варьироваться в зависимости от внутренних параметров, характерных для каждого чипа Bluetooth.Для вас нет настроек, позволяющих надежно сохранить ожидаемый размер пакета.

Вы должны сделать то же, что и для данных последовательного порта, наложить свои заголовки пакетов на данные, чтобы другая сторона могла собрать их.Это может быть так же просто, как отправка дополнительного двухбайтового значения длины перед остальной частью каждого пакета данных.Затем получатель получает поток данных с самоописанием.

...