工作原理
sntp
協議採用客戶
/伺服器工作方式,伺服器通過接收
gps訊號或自帶的原子鐘作為系統的時間基準,客戶機通過定期訪問伺服器提供的時間服務獲得準確的時間資訊,並調整自己的系統時鐘,達到網路時間同步的目的。
系統時鐘同步的工作過程如下:
device a
傳送乙個ntp報文給device b,該報文帶有它
離開device a
時的時間戳,該時間戳為10:00:00am(t1)。
當此ntp報文
到達device b
時,device b加上自己的時間戳,該時間戳為11:00:01am(t2)。
當此ntp報文
離開device b
時,device b再加上自己的時間戳,該時間戳為11:00:02am(t3)。
當device a
接收到該響應報文時,device a的本地時間為10:00:03am(t4)。
ntp報文的往返時延delay=(t4-t1)-(t3-t2)=2秒
device a
相對device b的時間差offset=((t2-t1)+(t3-t4))/2=1小時
報文格式
sntp
協議是udp協議的客戶,它利用udp的123埠提供服務,sntp客戶在設定請求資訊時要把udp目的埠設定為該值,源埠可以為任何非零值,伺服器在響應資訊中對這些值進行交換。同其它應用層協議一樣,sntp協議的資料通訊也是按資料幀的格式進行。
li:當前時間閏秒標誌。字段長度為2位整數,只在伺服器端有效。
li=0
:無警告;
li=1
:最後一分鐘是61秒;
li=2
:最後一分鐘是59秒;
li=3
:警告(時鐘沒有同步)
伺服器在開始時,
li設定為
3,一旦與主鍾取得同步後就設定成其它值。
vn:版本號。字段長度為3位整數,當前版本號為4。
mode
:指示協議模式。字段長度為3位,取值定義為:
mode=0
:保留
mode=1
:對稱主動;
mode=2
:對稱被動;
mode=3
:客戶;
mode=4
:伺服器;
mode=5
:廣播;
mode=6
:保留為ntp控制資訊;
mode=7
:保留為使用者定義;
在單播和多播模式,客戶在請求時把這個字段設定為3,伺服器在響應時把這個字段設定為4。在廣播模式下,伺服器把這個字段設定為5。
stratum:指示伺服器工作的級別,該字段只在伺服器端有效,字段長度為8位整數。取值定義為:
stratum=0
:故障資訊;
stratum=1
:一級伺服器;
stratum=2-15
:二級伺服器;
stratum=16-255
:保留;
poll interval:指示資料報的最大時間間隔,以秒為單位,作為2的指數方的指數部分,該字段只在伺服器端有效。字段長度為8位整數,取值範圍從4-17,即16秒到131,072秒。
precision:指示系統時鐘的精確性,以秒為單位,作為2的指數方的指數部分,該字段只在伺服器端有效。字段長度為8位符號整數,取值範圍從-6到-20。
root delay:指示與主時鐘參考源的總共往返延遲,以秒為單位,該字段只在伺服器端有效。字段長度為32位浮點數,小數部分在16位以後,取值範圍從負幾毫秒到正幾百毫秒。
root dispersion:指示與主時鐘參考源的誤差,以秒為單位,該字段只在伺服器端有效。字段長度為32位浮點數,小數部分在16位以後,取值範圍從零毫秒到正幾百毫秒。
reference identifier:指示時鐘參考源的標記,該字段只在伺服器端有效。對於一級伺服器,字段長度為4位元組ascii字串,左對齊不足添零。對於二級伺服器,在ipv4環境下,取值為一級伺服器的ip位址,在ipv6環境下,是一級伺服器的nsap位址。
reference timestamp:指示系統時鐘最後一次校準的時間,該字段只在伺服器端有效,以前面所述64位時間戳格式表示。
originate timestamp:指示客戶向伺服器發起請求的時間,以前面所述64位時間戳格式表示。
transmit timestamp:指示伺服器向客戶發時間戳的時間,以前面所述64位時間戳格式表示。
authenticator(可選):當需要進行sntp認證時,該欄位包含金鑰和資訊加密碼
基本工作過程
最常用工作模式-單播模式
sntp
伺服器在初始化時,stratum欄位設定為0,li欄位設定為3,mode 字段設定為3,reference identifier欄位設定為ascii字元「init」,所有時間戳資訊設定為0;
一旦sntp伺服器與外部時鐘源取得同步後,進入工作狀態,stratum欄位設定為1,li欄位設定為0,reference identifier欄位設定為外部時鐘源的ascii字元,如「gps」,precision欄位設定為-6到-20之間的乙個數值,通常設定為-16。vn欄位設定為客戶端請求資訊包的vn字段值,root delay和root dispersion欄位通常設定為0,reference timestamp欄位設定為從外部時鐘源最新取得的時間,originate timestamp欄位設定為客戶請求包的transmit timestamp字段值,transmit timestamp欄位設定為伺服器發出時間戳給客戶的時間。
sntp
伺服器在工作過程中,如果與外部時鐘源失去同步,stratum欄位設定為0,reference identifier欄位設定為故障原因的ascii字元,如:「lost」,此時客戶收到這個資訊時,要丟棄伺服器發給它的時間戳資訊。
兩種時間戳轉化的方法。
一、庫函式實現
#include #include #include #include typedef unsigned int u32_t;
typedef unsigned char u8_t;
typedef struct
realtime;
realtime unixtimestamp_to_beijingtime(u32_t time)
int main()
二、 程式設計運算實現
#include #include static int dayms = 24*3600;
static int fouryears = 365*3 + 366;
static int normonth = ;
static int leapmonth = ;
void gethms(int times)
void getmonandday(int ndays, int *nmonth, int *nday, bool isleapyear)
else
break;
} ndays = ntemp;
//printf("%d\n", ndays); }}
int main()
else if(nremain < 365 * 2)
else if(nremain < 365 * 3)
else
getmonandday(nremain, &ndecmonth, &ndecday, bleapyear);
printf("%d/%d/%d\n", ndecyear, ndecmonth, ndecday);
gethms(temp%dayms);
return 0;
}
Unix時間戳轉化時間
因為專案中經常用到unix時間戳的轉化,今天就總結一下 php中 這種方式在php程式中完成轉換,優點是無論是不是資料庫中查詢獲得的資料都能轉換,轉換範圍不受限制,缺點是占用php解析器的解析時間,速度相對慢。用函式 date 一般形式 date y m d h i s unix時間 php中將正常...
vue cli時間戳轉化時間
本人是乙個前端初學者,有一段時間使用vue cli 其中遇到一些問題。前端接收後台傳回的資料,其中最常見的就是時間戳,這樣就是需要我們自己轉化為時間格式 所以使用new date 處理 如下 xport function formatdate date,fmt let o for let k in ...
使用time模組,轉化時間格式
import time 時間戳 表示1970年開始計算的偏移量。我們運用type 時間戳 是float型別 格式化時間字串 獲取當前時間戳 print time.time 獲取地方時間 print time.localtime 指定時間格式 print time.strftime y m d x 把...