Время для прочтения: 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

Ссылки

Пошерить
Плюсануть
Отправить
Вотсап

WordPress Digest Мой канал в Телеграм, посвящённый WordPress

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

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

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

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

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

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

 

<?php
$fp = @fsockopen("udp://".$timeserver, $socket, $err, $errstr, 5);
// Где $socket = 123;
?>

Ну так вот и не вводите людей в заблуждение.
Цитата из wiki
—NTP не следует путать с daytime protocol RFC 867 или time protocol RFC 868—

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

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

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

 

<?
$fp = stream_socket_server(
	"udp://pool.ntp.org:123", 
	$errno, 
	$errstr, 
	STREAM_SERVER_BIND
);
?>

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

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

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

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

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

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

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

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

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

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

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

1. Нажимая на кнопку "Отправить", я даю согласие на обработку персональных данных.

2. Для вставки кода используйте специальные теги [code lang="php"]ваш код[/code]