ntp-clock
Время для прочтения: 1 мин. 7 сек.

Синхронизация времени с NTP — сервером на PHP (по протоколу DAYTIME)

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

Реализуем простую функцию для получения точного времени:

function queryTimeServer ($timeserver, $socket) {
    $timevalue = 0;
    $ret = array();
    $fp = @fsockopen($timeserver,$socket,$err,$errstr,5);
    if ($fp) {
    	fputs($fp,"\n");
    	$timevalue = fread($fp,49);
    	fclose($fp);
    }    
    $ret['time'] = $timevalue;
    $ret['errno'] = $err;
    $ret['errstr'] = $errstr;
    return $ret;
}

Используем, например, так:

// По умолчанию берем время с нашего сервера
$timevalue = time();

// Если запрос к NTP успешен - берем время из него
$timercvd = queryTimeServer("pool.ntp.org", 13);
if (!$timercvd['errno'] && $timercvd['time'] > 0) {
    $timevalue = strtotime($timercvd[0]);
}
echo "<p>Точное время: {$timevalue}</p>";

Для получения точного времени помимо pool.ntp.org также можно использовать следующие сервера:

  • time.windows.com
  • time.nist.gov
  • time-a.nist.gov
  • time-b.nist.gov
  • time-a.timefreq.bldrdoc.gov
  • time-b.timefreq.bldrdoc.gov
  • time-c.timefreq.bldrdoc.gov

Не следует путать daytime protocol RFC 867 с NTP или time protocol RFC 868

Ссылки

Для вставки кода используйте HTML-теги
<pre><code class="php">ваш код</code></pre>

Добавить комментарий

Такой e-mail уже зарегистрирован. Воспользуйтесь формой входа или введите другой.

Вы ввели некорректные логин или пароль

Извините, для комментирования необходимо войти.

10 комментариев

по хронологии
по рейтингу сначала новые по хронологии

Отлично написано! Лучшая статья на эту тему, которую я нашел. Кстати есть еще более простая синхронизация, можно почитать на http://sitemaker.x10.bz/articles.php?id=18

Автор
Кобзарёв Михаил

Так это тоже самое 🙂

--NTP использует для своей работы протокол UDP.--

Ну и где в вашем примере UDP? И разве NTP работает не на 123 udp порту?

Автор
Кобзарёв Михаил

Порт 13/TCP, UDP: протокол DAYTIME — предназначен для тестирования связи путём получения от сервера текущих даты и времени в текстовом виде (Ссылка в статье). Можно использовать 37 порт, но он устарел.

Ну так вот и не вводите людей в заблуждение.

Цитата из wiki

--NTP не следует путать с daytime protocol RFC 867 или time protocol RFC 868--

А то я уже обрадовался, думал и правда нашёл реализацию NTP на PHP 🙂

Автор
Кобзарёв Михаил

Что мешает сделать, например, так (подробности смотрите тут):

 

[php]

<?

$fp = stream_socket_server(

"udp://pool.ntp.org:123",

$errno,

$errstr,

STREAM_SERVER_BIND

);

?>

[/php]

А причем тут stream_socket_server? Зачем открывать у себя порт? Ваша статья же не о том как на php сделать сервер времени. Fsockopen() может прекрасно работать с udp, дело не в этом. Вы вначале процитировали wiki, о том, что такое NTP, а в коде реализовали DATETIME, который c NTP ничего общего не имеет.

Автор
Кобзарёв Михаил

Значит, мы друг друга не правильно поняли. Главное, чтобы серверный фаервол вас пропустил 🙂

 

[php]

<?php

$fp = @fsockopen("udp://".$timeserver, $socket, $err, $errstr, 5);

// Где $socket = 123;

?>

[/php]

Да нет, просто сменить порт и указать протокол, недостаточно. Этот самый алгоритм "Марзулло" нужно реализовывать в коде. В общем нужно копать RFC 🙂

Автор
Кобзарёв Михаил

Буду рад помочь. Статью я поправил. Сам того не замечая, писал про одно, а реализовал другое.