本帖最后由 iamlimeng 于 2019-08-11 19:51 編輯
最近在校準家里的時鐘,找了不少工具,獲得的時間都不太精確,還是自己寫吧。很久以前寫過一個,由于算法問題,精度不夠高,重寫了算法,現(xiàn)在精度應該在0.1秒以內(nèi)(前提是服務器時間精確)。
目前國內(nèi)比較可靠,網(wǎng)絡訪問延時少的授時服務器有:阿里云授時服務器、國家授時中心服務器、NTP.ORG,當然蘋果和微軟的授時服務器也不錯。
NTP(Network Time Protocol)網(wǎng)絡時間協(xié)議基于UDP,用于網(wǎng)絡時間同步的協(xié)議,使網(wǎng)絡中的計算機時鐘同步到UTC,再配合各個時區(qū)的偏移調(diào)整就能實現(xiàn)精準同步對時功能。NTP授時精度與NTP服務器與用戶間的網(wǎng)絡狀況有關:廣域網(wǎng)授時精度通常能達50ms級,但有時超過500ms;局域網(wǎng)授時不存在路由器路徑延遲問題,因而授時精度理論上可以提到亞毫秒級;但是Windows內(nèi)置NTP服務,在局域網(wǎng)內(nèi)其最高授時精度也只能達10ms級。
IETF的RFC5905對NTP數(shù)據(jù)包的結構有詳細說明。
萬能的Perl就有效率比較高的解析模塊Net::NTP,結合RFC5905文檔的說明,將NTP服務器反饋的數(shù)據(jù)包解析后,只須對接收到的時間數(shù)據(jù)進行延時修正,就能獲得準確的時間,這個精度對于一般用途足夠了。
代碼分享如下: - #!/usr/bin/perl
- =info
- Author: iamlimeng
- Date:2019-08
- =cut
- use strict;
- use warnings;
- use Net::NTP qw(get_ntp_response);
- $| = 1;
- my $interval = 0.999999;
- my $NTP_Server = 'ntp1.aliyun.com'; #阿里云授時服務器,可靠性高
- #my $NTP_Server = 'ntp.aliyun.com'; #阿里云授時服務器,可靠性高
- #my $NTP_Server = 'ntp.ntsc.ac.cn'; #國家授時中心,可靠性高
- #my $NTP_Server = 'cn.ntp.org.cn';
- print "NTP Server: $NTP_Server\n\n";;
- my %response = eval { get_ntp_response($NTP_Server) };
- if (%response) {
- my $time = $response{'Transmit Timestamp'} + $response{'Delay'}/2;
- my ($now,$wait) = split(/\./,$time);
- select(undef, undef, undef, 1-$wait/100000);
- while(1) {
- $now++;
- print "\r",time_from_utc($now);
- select(undef, undef, undef, $interval);
- }
- }
- else { print "Connect NTP Server Faild!"; }
- <STDIN>;
- exit;
- sub time_from_utc {
- my $utc = shift;
- my ($sec,$min,$hour,$day,$mon,$year,$weekday,$yeardate,$savinglightday) = (localtime($utc));
- return (sprintf("%04d.%02d.%02d %02d:%02d:%02d",$year+1900,$mon+1,$day,$hour,$min,$sec));
- }
復制代碼
|