Время для прочтения: 1 мин. 23 сек.

Синхронизация времени с 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 комментариев

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

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

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

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

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

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

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

 

[php]

<?php

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

// Где $socket = 123;

?>

[/php]

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

Цитата из 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]

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

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

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

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

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

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

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