iPhone: Отправка больших данных с Game Kit

Я преобразовал бы значения плавающие в целые числа как это:

unsigned int IntValue = (int)(floatValue * MULT) + MULT;

, таким образом, Вы получаете некоторые первые цифры и затем используете

const MULT1 = (MULT << 1) + 1;
unsigned long long HashValue = (xIntValue * MULT1  * MULT1) + (yIntValue * MULT1) + zIntValue;

как значение хэш-функции (использующий (MULT * 2) + 1, потому что IntValues будет между 0 и MULT * 2 содержащих).

необходимая память будет в зависимости от multiplicator MULT. Например, использование 32 Вы получите хеш-таблицу с помощью 64 * 64 * 64 * (Размер объекта хеша) = 262144 * (Размер объекта хеша) байты.

5
задан pnuts 25 November 2015 в 17:39
поделиться

2 ответа

У меня была та же проблема с файлами размером около 300 КБ. Проблема в том, что отправитель должен знать, когда получатель опустошил канал, прежде чем отправлять следующий фрагмент.

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

Получатель получает каждый пакет, считывает его и добавляет в буфер, а затем записывает обратно в конвейер полученный пакет с последовательностью #. Отправитель читает пакет №, вырезает значение другого буфера и т. Д. И т. Д. Каждая сторона отслеживает состояние, в котором они находятся (бездействие, отправка заголовка, получение заголовка, отправка данных, получение данных, ошибка, выполнение и т. д.) Обе стороны должны отслеживать, когда следует читать / записывать последний фрагмент, поскольку он, вероятно, будет меньше, чем полный размер буфера.

Это отлично работает ( хотя и немного медленно), и его можно масштабировать до любого размера. Я начал с пакетов размером 5К, но все прошло довольно медленно. Увеличил его до 10 КБ, но это начало вызывать проблемы, поэтому я отступил и оставил его на 8096. Он отлично работает как для двоичных, так и для текстовых данных.

4
ответ дан 14 December 2019 в 08:57
поделиться

Имейте в виду, что GameKit не является общим API для передачи файлов; это больше предназначено для обновления информации о том, где находится игрок, каково текущее местоположение или другие объекты и т. д. Так что отправка 300 КБ для игры не кажется такой уж разумной, хотя я могу понять, как взломать API для общих механизмов обмена.

проблема в том, что это не TCP-соединение; это больше соединение UDP (датаграмма). В этих случаях данные не являются потоком (который пакетируется TCP), а скорее гигантским фрагментом данных. (Технически UDP может быть фрагментирован на несколько IP-пакетов, но при этом теряется один из них, и весь UDP теряется, в отличие от TCP, который будет повторять попытку).

MTU для большинства проводных сетей составляет ~ 1,5 КБ. ; для блютуза это около ~ 0,5к. Таким образом, любой отправленный вами UDP-пакет (а) может быть потерян, (b) могут быть разделены на несколько IP-пакетов размером с MTU, и (c) если один из этих пакетов потерян, вы автоматически потеряете весь набор.

Лучшая стратегия - эмулировать TCP - он отправляет пакеты с порядковым номером. Затем принимающая сторона может запросить дублирующую передачу пакетов, которые впоследствии пропали. Если вы используете эквивалент NSKeyedArchiver, то одно из предложений - перебрать ключи и записать их как отдельные ключи (при условии, что каждое ключевое значение не такое уж большое само по себе). Вам нужно будет иметь какой-то ACK для каждого пакета, который будет отправлен обратно, и общий ACK, когда вы закончите, чтобы отправитель знал, что можно удалить данные из памяти.

Лучшая стратегия - имитировать TCP - он отправляет пакеты с порядковым номером. Затем принимающая сторона может запросить дублирующую передачу пакетов, которые впоследствии пропали. Если вы используете эквивалент NSKeyedArchiver, то одно из предложений - перебрать ключи и записать их как отдельные ключи (при условии, что каждое ключевое значение не такое уж большое само по себе). Вам нужно будет иметь какой-то ACK для каждого пакета, который будет отправлен обратно, и общий ACK, когда вы закончите, чтобы отправитель знал, что можно удалить данные из памяти.

Ваша лучшая стратегия - эмулировать TCP - он отправляет пакеты с порядковым номером. Затем принимающая сторона может запросить дублирующую передачу пакетов, которые впоследствии пропали. Если вы используете эквивалент NSKeyedArchiver, то одно из предложений - перебрать ключи и записать их как отдельные ключи (при условии, что каждое ключевое значение само по себе не такое уж большое). Вам нужно будет иметь какой-то ACK для каждого пакета, который будет отправлен обратно, и общий ACK, когда вы закончите, чтобы отправитель знал, что можно удалить данные из памяти.

тогда одно из предложений - перебрать ключи и записать их как отдельные ключи (при условии, что каждое ключевое значение не такое уж большое само по себе). Вам нужно будет иметь какой-то ACK для каждого пакета, который будет отправлен обратно, и общий ACK, когда вы закончите, чтобы отправитель знал, что можно удалить данные из памяти.

тогда одно из предложений - перебрать ключи и записать их как отдельные ключи (при условии, что каждое ключевое значение не такое уж большое само по себе). Вам нужно будет иметь какой-то ACK для каждого пакета, который будет отправлен обратно, и общий ACK, когда вы закончите, чтобы отправитель знал, что можно удалить данные из памяти.

3
ответ дан 14 December 2019 в 08:57
поделиться