Подтвердить что ты не робот

Измерение разницы во времени между сетевыми устройствами

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

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

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

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

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


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

4b9b3361

Ответ 1

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

Пусть s равно времени в соответствии с сервером. Пусть 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 мс. Оказывается, наиболее точным является использование временных меток с минимальным временем пинга. Это потому, что ваше время ping - это сумма задержки "голого металла" плюс любые задержки, ожидающие ожидания в очередях маршрутизатора. Время от времени счастливый пакет проходит без каких-либо задержек в очереди, поэтому вы используете это минимальное время как наиболее повторяемое время.

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

Надеемся, что это поможет вам в правильном направлении.

Ответ 2

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

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

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