2010-09-20 2 views
12

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

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

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

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

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


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

ответ

23

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

Позвольте времени равным времени в зависимости от сервера. Пусть 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, вычисленных с течением времени, для вычисления вашего дрейфа и компенсации его между измерениями, но это выходит за рамки ответа здесь.

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

+0

Ничего себе! Благодаря! Это именно то, что я ищу. Мне еще не совсем ясно, почему это лучше, чем мой оригинальный метод (хотя я считаю, что это так), но я отправлю туда, когда я попробую. Я не думаю, что мне нужно будет настроить d на игровой сессии, но мне не составит труда сделать это, если мне нужно. Еще раз спасибо! – whooops

+0

Это сработало очень хорошо. Я обнаружил, что если я всегда принимаю наименьшие (т. Е. Самые отрицательные) значения t1 и t2, это то же самое, что и самые маленькие пинги, поэтому он сходится на правильном смещении. Я t1 = клиент штамп - сервер штамп и t2 = печать сервер - клиент марка Кроме того, я обнаружил, что Iphones дрейфуют довольно значительно! В течение получаса фактическое смещение между двумя устройствами может меняться на полсекунды. Я проверил это с часовыми программами, которые связывают NTP-серверы. – whooops

+0

Рад, что это было полезно для вас. –

2

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

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

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

+0

Спасибо. Я думаю, что попробую алгоритм, указанный в ответе выше, и попросите совета по использованию нескольких образцов. – whooops

Смежные вопросы