Измерение разницы во времени между сетевыми устройствами - PullRequest
14 голосов
/ 21 сентября 2010

Я добавляю сетевой мультиплеер в игру, которую я сделал. Когда сервер отправляет клиенту пакет обновления, я включаю метку времени, чтобы клиент точно знал, когда эта информация верна. Однако на сервере и клиентском компьютере часы могут быть установлены на разное время (может быть, даже с разницей в несколько секунд), поэтому метку времени с сервера необходимо преобразовать в местное время клиента.

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

Но проблема в том, что я получаю разные результаты при повторных запусках программы. В пределах каждого набора из 10 каждое измерение редко расходится более чем на 400 миллисекунд, что может быть приемлемым. Но если я подожду несколько минут между каждым запуском программы, полученные средние значения могут не совпадать на целых 2 секунды, что недопустимо.

Есть ли лучший способ выяснить разницу между часами двух сетевых устройств? Или есть хотя бы способ настроить мой алгоритм для получения более точных результатов?

Подробности, которые могут иметь или не иметь отношение: Устройства iPod Touches обмениваются данными через Bluetooth. Я измеряю эхо-запросы от 50 до 200 миллисекунд. Я не могу попросить пользователей синхронизировать свои часы. :)


Обновление: с помощью приведенных ниже ответов я написал для этого класс Objective-C. Я разместил это в своем блоге: http://scooops.blogspot.com/2010/09/timesync-was-time-sink.html

Ответы [ 2 ]

24 голосов
/ 21 сентября 2010

Недавно я взял урок на один час, и этого было недостаточно, но я постараюсь свести его к минимуму, чтобы вы указали правильное направление.Приготовьтесь к небольшой алгебре.

Давайте сравним время в соответствии с сервером.Пусть c равняется времени в соответствии с клиентом.Пусть d = s - c.d - это то, что добавляется к времени клиента, чтобы скорректировать его к времени сервера, и это то, для чего мы должны решить.

Сначала мы отправляем пакет с сервера клиенту с отметкой времени.Когда этот пакет получен на клиенте, он сохраняет разницу между данной временной меткой и своими собственными часами как t1.

Затем клиент отправляет пакет на сервер со своей собственной временной меткой.Сервер отправляет разность между отметкой времени и собственными часами обратно клиенту как t2.

Обратите внимание, что оба t1 и t2 включают в себя «время прохождения» t пакета плюс разницу во времени между двумя часами d,Предполагая на данный момент, что время прохождения одинаково в обоих направлениях, теперь у нас есть два уравнения с двумя неизвестными, которые могут быть решены:

t1 = t - d
t2 = t + d
t1 + d = t2 - d
d = (t2 - t1)/2

Хитрость заключается в том, что время в пути не всегда постоянное,что подтверждается вашими пингами от 50 до 200 мс.Оказывается, наиболее точно использовать временные метки с минимальным временем пинга.Это потому, что ваше время пинга является суммой задержки «голого металла» плюс любые задержки, затраченные на ожидание в очередях маршрутизатора.Время от времени удачный пакет проходит без каких-либо задержек в очереди, поэтому вы используете это минимальное время как самое повторяемое время.

Также имейте в виду, что часы работают с разной скоростью.Например, я могу сбросить свой компьютер дома до миллисекунды, а через день он будет медленным на 8 секунд.Это означает, что вы должны постоянно корректировать d.Вы можете использовать наклон различных значений d, вычисленных с течением времени, чтобы рассчитать ваш дрейф и компенсировать его между измерениями, но это выходит за рамки ответа здесь.

Надеюсь, что поможет вам указать правильное направление.

2 голосов
/ 21 сентября 2010

Ваш алгоритм не будет намного более точным, если вы не сможете использовать некоторые статистические методы. Прежде всего, 10, вероятно, недостаточно. Первым и самым простым изменением было бы собрать 100 образцов времени прохождения и выбросить x самых длинных и самых коротких.

Еще одна вещь, которую нужно добавить, это то, что оба клиента отправляют свою собственную метку времени в каждом пакете. Затем вы также можете рассчитать, насколько отличаются их часы, и проверить среднюю разницу между часами.

Вы также можете специально проверить реализации STNP и NTP, поскольку эти протоколы делают это специально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...