<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      NTP服務(wù)器

      1、NTP服務(wù)器

        NTP協(xié)議是網(wǎng)絡(luò)時間協(xié)議(Network Time Protocol),它是用來同步網(wǎng)絡(luò)中各個計算機的時間的協(xié)議。它的用途是把計算機的時鐘同步到世界協(xié)調(diào)時UTC,其精度在局域網(wǎng)內(nèi)可達(dá)0.1ms,在互聯(lián)網(wǎng)上絕大多數(shù)的地方其精度可以達(dá)到1-50ms。它可以使計算機對其服務(wù)器或時鐘源(如石英鐘,GPS等等)做同步化,它可以提供高精準(zhǔn)度的時間校正(LAN上與標(biāo)準(zhǔn)間差小于1毫秒,WAN上幾十毫秒),且可介由加密確認(rèn)的方式來防止惡毒的協(xié)議攻擊。時間按NTP服務(wù)器的等級傳播。按照離外部UTC源的遠(yuǎn)近把所有服務(wù)器歸入不同的Stratum(層)中。

        NTP要提供準(zhǔn)確的時間,就必須有準(zhǔn)確的時間來源,那可以用格林尼治時間嗎?答案是否定的。因為格林尼治時間是以地球自轉(zhuǎn)為基礎(chǔ)的時間計量系統(tǒng),但是地球每天的自轉(zhuǎn)是有些不規(guī)則的,而且正在緩慢加速,因此,格林尼治時間已經(jīng)不再被作為標(biāo)準(zhǔn)時間使用。

        新的標(biāo)準(zhǔn)時間,是由原子鐘報時的國際標(biāo)準(zhǔn)時間UTC(Universal Time Coordinated,世界協(xié)調(diào)時)。所以NTP獲得UTC的時間來源可以是原子鐘、天文臺、衛(wèi)星,也可以從Internet上獲取。

        有了準(zhǔn)確而可靠的的時間源,那這個時間如何傳播呢?

        NTP提供準(zhǔn)確時間,首先要有準(zhǔn)確的時間來源,這一時間應(yīng)該是國際標(biāo)準(zhǔn)時間UTC。 NTP獲得UTC的時間來源可以是原子鐘、天文臺、衛(wèi)星,也可以從Internet上獲取。這樣就有了準(zhǔn)確而可靠的時間源。在NTP中,定義了時間按照服務(wù)器的等級傳播,按照離外部UTC源遠(yuǎn)近將所有的服務(wù)器歸入不同的Stratum(層)中,時間按NTP服務(wù)器的等級傳播。按照離外部UTC 源的遠(yuǎn)近將所有服務(wù)器歸入不同的Stratum(層)中。Stratum-1在頂層,有外部UTC接入,而Stratum-2則從Stratum-1獲取時間,Stratum-3從Stratum-2獲取時間,以此類推,但Stratum層的總數(shù)限制在15以內(nèi)。所有這些服務(wù)器在邏輯上形成階梯式的架構(gòu)相互連接,而Stratum-1的時間服務(wù)器是整個系統(tǒng)的基礎(chǔ)。

        計算機主機一般同多個時間服務(wù)器連接, 利用統(tǒng)計學(xué)的算法過濾來自不同服務(wù)器的時間,以選擇最佳的路徑和來源來校正主機時間。即使主機在長時間無法與某一時間服務(wù)器相聯(lián)系的情況下,NTP服務(wù)依然有效運轉(zhuǎn)。

        為防止對時間服務(wù)器的惡意破壞,NTP使用了識別(Authentication)機制,檢查來對時的信息是否是真正來自所宣稱的服務(wù)器并檢查資料的返回路徑,以提供對抗干擾的保護(hù)機制。

      2、UTC

        協(xié)調(diào)世界時,即格林威治平太陽時間,又稱世界統(tǒng)一時間、世界標(biāo)準(zhǔn)時間、國際協(xié)調(diào)時間。由于英文(CUT)和法文(TUC)的縮寫不同,作為妥協(xié),簡稱UTC。

        協(xié)調(diào)世界時是以原子時秒長為基礎(chǔ),在時刻上盡量接近于世界時的一種時間計量系統(tǒng)。中國大陸采用ISO 8601-1988的《數(shù)據(jù)元和交換格式信息交換日期和時間表示法》(GB/T 7408-1994)稱之為國際協(xié)調(diào)時間,代替原來的GB/T 7408-1994;中國臺灣采用CNS 7648的《資料元及交換格式–資訊交換–日期及時間的表示法》,稱之為世界統(tǒng)一時間。

        這套時間系統(tǒng)被應(yīng)用于許多互聯(lián)網(wǎng)和萬維網(wǎng)的標(biāo)準(zhǔn)中,例如,網(wǎng)絡(luò)時間協(xié)議就是協(xié)調(diào)世界時在互聯(lián)網(wǎng)中使用的一種方式。

        GMT(Greenwich Mean Time,格林威治時間)是英國格林尼治當(dāng)?shù)貢r間,它和UTC是的時間是一樣的,及GMT=UTC+0。

        在軍事中,協(xié)調(diào)世界時區(qū)會使用“Z”來表示。又由于Z在無線電聯(lián)絡(luò)中使用“Zulu”作代稱,協(xié)調(diào)世界時也會被稱為"Zulu time"。中國大陸、中國香港、中國澳門、中國臺灣、蒙古國、新加坡、馬來西亞、菲律賓、西澳大利亞州的時間與UTC的時差均為+8,也就是UTC+8。

      3、NTP報文格式

        NTP是從時間協(xié)議(Time Protocol)和ICMP時間戳報文(ICMP TimeStamp Message)演變而來,在準(zhǔn)確性和健壯性方面進(jìn)行了特殊的設(shè)計,理論上精度可達(dá)十億分之一秒。

        NTP協(xié)議應(yīng)用于分布式時間服務(wù)器和客戶端之間,實現(xiàn)客戶端和服務(wù)器的時間同步,從而使網(wǎng)絡(luò)內(nèi)所有設(shè)備的時鐘基本保持一致。

        NTP協(xié)議是基于UDP進(jìn)行傳輸?shù)模褂枚丝谔枮?23。

                  圖1 NTP數(shù)據(jù)報文格式 
       
      字段名長度含義
      LI(Leap Indicator) 2比特 這是一個兩位的代碼,表示在NTP時間標(biāo)尺中將要插入的下一跳情況。值為“11”時表示告警狀態(tài),時鐘不能被同步。
      VN(Version Number) 3比特 NTP的版本號。
      Mode 3比特

      NTP的工作模式。不同值表示的含義如下:

      0:reserved,保留。

      1:symmetric active,主動對等體模式。

      2:symmetric passive,被動對等體模式。

      3:client,客戶模式。

      4:server,服務(wù)器模式。

      5:broadcast,廣播模式。

      6:reserved for NTP control messages,NTP控制報文。

      7:reserved for private use,內(nèi)部使用預(yù)留。

      Stratum 8比特 時鐘的層數(shù),定義了時鐘的準(zhǔn)確度。層數(shù)為1的時鐘準(zhǔn)確度最高,從1到15依次遞減。
      Poll Interval 8比特 輪詢時間,即發(fā)送報文的最小間隔時間。
      Precision 8比特 時鐘的精度。
      Root Delay 32比特 到主參考時鐘的總往返延遲時間。
      Root Dispersion 32比特 本地時鐘相對于主參考時鐘的最大誤差。
      Reference Identifier 32比特 標(biāo)識特定參考時鐘。
      Reference Timestamp 64比特 本地時鐘最后一次被設(shè)定或更新的時間。如果值為0表示本地時鐘從未被同步過。
      Originate Timestamp 64比特 NTP報文離開源端時的本地時間。
      Receive Timestamp 64比特 NTP報文到達(dá)目的端的本地時間。
      Transmit Timestamp 64比特 目的端應(yīng)答報文離開服務(wù)器端的本地時間。
      Authenticator 96比特 (可選)驗證信息。
                                
                  圖2 NTP控制報文格式 
       
      字段名長度含義
      0 2比特 保留位。NTP本身不做處理。
      VN(Version Number) 3比特 NTP的版本號,目前值為3。
      6 3比特 表明是控制報文。
      REM 3比特

      R:0表示命令,1表示響應(yīng)。

      E:0表示發(fā)送正常響應(yīng),1表示發(fā)送錯誤響應(yīng)。

      M:0表示最后一個分片,1表示其他。

      Op 5比特 操作碼,表明命令的類型。
      Sequence 16比特 發(fā)送或接受到報文的順序號。
      Status 16比特 表明當(dāng)前系統(tǒng)的狀態(tài)。
      Association ID 16比特 連接標(biāo)示。
      Offset 16比特 偏移量。
      Count 16比特 數(shù)據(jù)域的長度。
      Data 最大468比特 包括發(fā)送報文或接受報文中的數(shù)據(jù)信息。
      Padding 16比特 填充字段。
      Authenticator 96比特 (可選)驗證信息。
       
      2、訪問NTP服務(wù)器
       
      //NTP的端口號
      NTP_PORT                    123    
      
      
      //常見的NTP的IP地址
      uint8_t ntp_server_ip[4]={103,11,143,248};        //新加坡
      uint8_t ntp_server_ip[4]={133,243,238,243};       //日本東京
      uint8_t ntp_server_ip[4]={85,199,214,100};        //英國
      uint8_t ntp_server_ip[4] = {202,120,2,101};       //上海交通大學(xué)ntp服務(wù)器IP地址202.120.2.101
      uint8_t ntp_server_ip[4] = {210,72,145,44};       //國家授時中心服務(wù)器IP地址    210,72,145,44
      uint8_t ntp_server_ip[4] = {202,118,1,81};        //遼寧省沈陽市 教育網(wǎng)
      uint8_t ntp_server_ip[4]={203,107,6,88};          //阿里云
      uint8_t ntp_server_ip[4]={120,25,115,20};         //阿里云
      uint8_t ntp_server_ip[4]={120,25,108,11};         //阿里云
      //報文結(jié)構(gòu)體
      typedef struct NTP_MessageTypeDef
      {
          unsigned int        leap                : 2;/* leap indicator */
          unsigned int        version             : 3;/* version number       ntp版本號*/
          unsigned int        mode                : 3;/* mode                 ntp工作模式*/
          unsigned int        stratum             : 8;/* stratum              時鐘層數(shù)*/
          unsigned int        poll                : 8;/* poll interval        輪詢時間*/
          unsigned int        precision           : 8;/* precision            時鐘的精度*/
          unsigned int        rootdelay;              /* root delay           到主參考時鐘的總往返延遲時間*/
          unsigned int        rootdisp;               /* root dispersion      本地時鐘相對于主參考時鐘的最大誤差*/
          unsigned int        refid;                  /* reference ID         標(biāo)識特定參考時鐘*/
          unsigned long long  reftime;                /* reference time       本地時鐘最后一次被設(shè)定或更新的時間*/
          unsigned long long  oritime;                /* origin timestamp     NTP報文離開源端時的本地時間*/
          unsigned long long  rectime;                /* receive timestamp    NTP報文到達(dá)目的端的本地時間*/
          unsigned long long  tratime;                /* transmit timestamp   目的端應(yīng)答報文離開服務(wù)器端的本地時間*/
          unsigned int        Authenticator[3];        /* Authenticator       (可選)驗證信息 */
      } NTP_MessageTypeDef;
      Leap Indicator(LI) :閏秒指示符,這是一個2位的代碼,用于警示在當(dāng)天的最后一分鐘里插入或刪除的閏秒。取值如下:
        0:無預(yù)告
        1:最近一分鐘有61秒   
        2:最近一分鐘有59秒   
        3:警告狀態(tài)(時鐘未同步)
      
      Version Number(VN) :版本號,這是一個3位的整數(shù),用于表示NTP的版本。
      
      Mode :模式,這是一個3位的整數(shù),表示模式,值定義如下:
        0:保留
        1:對稱主動
        2:對稱被動
        3:客戶端
        4:服務(wù)器端
        5:廣播
        6:為NTP控制控制消息
        7:為自用保留
      
      Stratum :本地時鐘層級,這是一個八位無符號整數(shù),表示本地時鐘的層級,其值定義如下:
        0:未定義或難以獲得
        1:主要參考(如無線電時鐘鐘,校正的院子時鐘)
        2-255:第二參考(通過NTP或SNTP)
      
      Poll :輪詢間隔,這是一個8位有符號整數(shù),用于表示連續(xù)消息之間的最大間隔,以最接近2的N次冪來表示。如值為6表示2^6=64。
      
      Precision :本地時鐘精度精度,這是一個8位有符號整數(shù),用于表示本地時鐘精度,以最接近2的N次冪來表示。
      
      Root Delay :這是一個32位有符號定點數(shù),表示主要參考源的總往返時延,以秒為單位。該變量可以為正值和負(fù)值,具體取決于時間精度和偏移。
      
      Root Dispersion :這是一個32位有符號定點數(shù),表示相對于主參考源的最大誤差,以秒為單位,在15和16位之間。通常在該字段中出現(xiàn)的值范圍為0到幾百毫秒
      
      Reference Identifier :這是一個標(biāo)識特定參考源的32位位串。在NTP版本3或版本4層級0或?qū)蛹?服務(wù)器的情況下,這是一個4字符ASCII字符串,左對齊并且以0填充到32位。在NTP版本3輔助服務(wù)器中,這是參考源的32位IPv4地址。
      
      Reference Timestamp :這是以64位時間戳格式表示的上次設(shè)置或更正的本地時鐘時間。
      
      Original Timestamp :這是以64位時間戳格式表示的請求離開客戶端的時間。
      
      Receive Timestamp :這是以64位時間戳格式表示的請求到達(dá)服務(wù)器端的時間。
      
      Transmit Timestamp :這是以64位時間戳格式表示的應(yīng)答離開服務(wù)器端的時間。
      
      Authentication :認(rèn)證信息。

       

       

       

       測試程序

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      #include<winsock2.h>
      
      #pragma comment(lib,"ws2_32.lib")
      
      
      
      typedef unsigned char            uint8_t;
      typedef unsigned short int        uint16_t;
      typedef unsigned int            uint32_t;
      
      
      
      #define NTP_PORT                    123                        //NTP的端口
      
      
      #define SECS_PERDAY                    86400UL                 // 一天的秒數(shù) day = 60*60*24
      #define NTP_START_TIME_YEAR            1900                //微軟的時間戳是從1900.1.1算起,而unix的時間戳是從1970.1.1算起
      #define FOUR_YEAR_DAYS                 (366+365+365+365)    //4年一個周期內(nèi)的總天數(shù)(NTP_START_TIME_YEAR~2038不存在2100這類年份,故暫不優(yōu)化)1900開始:(366+365+365+365),但是1900不是閏年,計算完后要加1天  1970開始:(365+365+366+365)
      
      
      
      
      #define BUFFER_SIZE                    1024    //緩沖區(qū)大小
      
      
      
      
      //NTP服務(wù)器報文
      typedef struct NTP_MessageTypeDef
      {
          unsigned int        leap : 2;/* leap indicator */
          unsigned int        version : 3;/* version number          ntp版本號*/
          unsigned int        mode : 3;/* mode                 ntp工作模式*/
          unsigned int        stratum : 8;/* stratum              時鐘層數(shù)*/
          unsigned int        poll : 8;/* poll interval        輪詢時間*/
          unsigned int        precision : 8;/* precision            時鐘的精度*/
          unsigned int        rootdelay;              /* root delay            到主參考時鐘的總往返延遲時間*/
          unsigned int        rootdisp;               /* root dispersion        本地時鐘相對于主參考時鐘的最大誤差*/
          unsigned int        refid;                  /* reference ID            標(biāo)識特定參考時鐘*/
          unsigned long long  reftime;                /* reference time        本地時鐘最后一次被設(shè)定或更新的時間*/
          unsigned long long  oritime;                /* origin timestamp        NTP報文離開源端時的本地時間*/
          unsigned long long  rectime;                /* receive timestamp    NTP報文到達(dá)目的端的本地時間*/
          unsigned long long  tratime;                /* transmit timestamp    目的端應(yīng)答報文離開服務(wù)器端的本地時間*/
          unsigned int        Authenticator[3];        /* Authenticator           (可選)驗證信息 */
      } NTP_MessageTypeDef;
      
      
      
      
      
      typedef struct NTP_TimeTypeDef
      {
          uint16_t year;        //
          uint8_t  month;        //
          uint8_t  date;        //
          uint8_t  week;        //星期
          uint8_t     hour;        //小時
          uint8_t  minute;    //分鐘
          uint8_t  second;    //秒鐘
      
          unsigned long long time_s;    //秒時間
      }NTP_TimeTypeDef;

       

       

       

      #include "ntp.h"
      
      
      static uint8_t peace_month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//平年每個月的天數(shù)
      static uint8_t leap_month_days[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //閏年每個月的天數(shù)
      
      
      /************************************************************************************************
      * @ 函 數(shù) 名:NTP_GenerateReqMessage
      * @ 功能說明:生成NTP服務(wù)器請求報文
      * @ 參    數(shù):p_Message_Buf:報文緩沖區(qū)
      * @ 返 回 值:無
      ************************************************************************************************/
      static void NTP_GenerateReqMessage(uint8_t *p_Message_Buf)
      {
          NTP_MessageTypeDef NTP_MessageStruct;
      
          NTP_MessageStruct.leap = 0;
          NTP_MessageStruct.version = 4;
          NTP_MessageStruct.mode = 3;
          NTP_MessageStruct.stratum = 0;
          NTP_MessageStruct.poll = 0;
          NTP_MessageStruct.precision = 0;
          NTP_MessageStruct.rootdelay = 0;
          NTP_MessageStruct.rootdisp = 0;
          NTP_MessageStruct.refid = 0;
          NTP_MessageStruct.reftime = 0;
          NTP_MessageStruct.oritime = 0;
          NTP_MessageStruct.rectime = 0;
          NTP_MessageStruct.tratime = 1;
          NTP_MessageStruct.Authenticator[0] = 0;
          NTP_MessageStruct.Authenticator[1] = 0;
          NTP_MessageStruct.Authenticator[2] = 0;
      
      
          //memcpy((void *)p_Message_Buf, (void const*)(&NTP_MessageStruct), sizeof(NTP_MessageStruct));
      
          uint8_t temp = 0;
          temp = (NTP_MessageStruct.leap << 6) + (NTP_MessageStruct.version << 3) + (NTP_MessageStruct.mode);
      
          p_Message_Buf[0] = 0x23;  // 0x23 = NTP_MessageStruct.leap << 6 + NTP_MessageStruct.version << 3 + NTP_MessageStruct.mode    
      
          return;
      }
      
      
      
      
      
      
      
      /************************************************************************************************
      * @ 函 數(shù) 名:NTP_WeekCalculate
      * @ 功能說明:根據(jù)日期計算星期
      * @ 參    數(shù):p_NTP_TimeStruct:時間結(jié)構(gòu)體
      * @ 返 回 值:無
      ************************************************************************************************/
      static uint8_t NTP_WeekCalculate(NTP_TimeTypeDef *p_NTP_TimeStruct)
      {
          uint16_t year = 0;
          uint8_t month = 0;
          uint8_t date = 0;
          uint8_t week = 0;
      
          year = p_NTP_TimeStruct->year;
          month = p_NTP_TimeStruct->month;
          date = p_NTP_TimeStruct->date;
      
      
          if (month == 1 || month == 2)
          {
              month += 12;
              year--;
          }
      
          week = (date + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7;
      
          return (week + 1);
      }
      
      
      
      
      
      /************************************************************************************************
      * @ 函 數(shù) 名:NTP_Leapyearjudgment
      * @ 功能說明:判斷是否是閏年
      * @ 參    數(shù):Year:年
      * @ 返 回 值:0: 平年    1:閏年
      ************************************************************************************************/
      static uint8_t NTP_Leapyearjudgment(uint16_t Year)
      {
          uint8_t ret = 0;
      
          if (Year % 400 == 0)//能被400整除的就是閏年
          {
              ret = 1;
          }
          else
          {
              if (Year % 4 == 0 && Year % 100 != 0)//不能被400整除,但是能被4整除并且不能被100整除是閏年
              {
                  ret = 1;
              }
              else//不能被400整除,但是不能被4整除或者能被100整除是平年
              {
                  ret = 0;
              }
          }
      
          return ret;
      }
      
      
      
      
      
      /************************************************************************************************
      * @ 函 數(shù) 名:NTP_DateToTimeStamp
      * @ 功能說明:日期轉(zhuǎn)換成時間戳
      * @ 參    數(shù):NTP_TimeStruct:時間結(jié)構(gòu)體
      * @ 返 回 值:時間戳
      ************************************************************************************************/
      uint32_t NTP_DateToTimeStamp(NTP_TimeTypeDef *p_NTP_TimeStruct)
      {
          uint16_t year_temp = NTP_START_TIME_YEAR, month_temp = 1;    //時間戳的起始時間
          uint32_t day_num = 0, second_num = 0;                        //保存當(dāng)前時間到時間戳起始時間的天數(shù)
      
      
          //1.計算從NTP_START_TIME_YEAR年到當(dāng)前時間前一年的總天數(shù)   如當(dāng)前時間為2021.6.15  12.30.30,就計算從NTP_START_TIME_YEAR年到2020年的總天數(shù)
          while (year_temp < p_NTP_TimeStruct->year)
          {
              if (NTP_Leapyearjudgment(year_temp))//判斷是否為閏年
              {
                  day_num += 366;//閏年366天
              }
              else
              {
                  day_num += 365;//平年365天
              }
              year_temp++;
          }
      
      
      
          //2.計算當(dāng)前年份的1月到前一個月的總天數(shù)   如當(dāng)前時間為2021.6.15  12.30.30,就計算從2021年1月到5月的總天數(shù)
          while (month_temp < (p_NTP_TimeStruct->month))
          {
              if (NTP_Leapyearjudgment(p_NTP_TimeStruct->year)) //判斷當(dāng)前年是否為閏年
              {
                  day_num += leap_month_days[month_temp - 1];//閏年各個月的天數(shù)
              }
              else
              {
                  day_num += peace_month_days[month_temp - 1];//平年各個月的天數(shù)
              }
              month_temp++;
          }
      
      
      
          //3.計算當(dāng)前月份的1號到前一天的天數(shù)  如當(dāng)前時間為2021.6.15  12.30.30,就計算從2021.6.1到2021.6.14的總天數(shù)為14天
          day_num += (p_NTP_TimeStruct->date - 1);
      
      
      
          //4.計算當(dāng)前時分秒
          second_num = day_num * 24 * 60 * 60; //從1900/1/1 00:00:00到當(dāng)前時間前一天的總秒數(shù) 
          second_num += p_NTP_TimeStruct->hour * 60 * 60;
          second_num += p_NTP_TimeStruct->minute * 60;
          second_num += p_NTP_TimeStruct->second;
      
      
          return second_num;
      }
      
      
      
      
      
      /************************************************************************************************
      * @ 函 數(shù) 名:NTP_TimeStampToDate
      * @ 功能說明:時間戳轉(zhuǎn)換成日期
      * @ 參    數(shù):Time_Stamp:時間戳      NTP_TimeStruct:時間結(jié)構(gòu)體
      * @ 返 回 值:無
      ************************************************************************************************/
      void NTP_TimeStampToDate(uint32_t Time_Stamp, NTP_TimeTypeDef *p_NTP_TimeStruct)
      {
          uint32_t totle_day_num = 0, totle_second_num = 0;
          uint16_t remain_day_of_year = 0;
          uint16_t year_temp = 0;
          uint8_t *p_str = NULL;
      
          totle_day_num = (Time_Stamp) / (24 * 60 * 60);        //計算過去的總天數(shù)(注意加括號)
          totle_second_num = (Time_Stamp) % (24 * 60 * 60);    //計算當(dāng)天過去的秒數(shù)
      
          memset((void *)p_NTP_TimeStruct, 0x00, sizeof(NTP_TimeTypeDef));
      
      
          //1.先計算時分秒 HH:MM:SS
          p_NTP_TimeStruct->hour = totle_second_num / 3600;
          p_NTP_TimeStruct->minute = (totle_second_num % 3600) / 60;
          p_NTP_TimeStruct->second = (totle_second_num % 3600) % 60;
      
      
          //2.計算哪一年
          p_NTP_TimeStruct->year = NTP_START_TIME_YEAR + (totle_day_num / FOUR_YEAR_DAYS) * 4;    //4年為一個周期,先計算過了幾個4年周期,比如當(dāng)前為2021,計算出來就是2020,那么就是從NTP_START_TIME_YEAR~2019這120年
          remain_day_of_year += totle_day_num % FOUR_YEAR_DAYS;                //4年一個周期剩余的天數(shù)
          if (NTP_START_TIME_YEAR == 1900)    //因為1900~1903連續(xù)四年都是平年,所以如果是從1900年開始計算,計算完后得重新加1天
          {
              remain_day_of_year++;
          }
      
          year_temp = NTP_Leapyearjudgment(p_NTP_TimeStruct->year) ? 366 : 365;//計算當(dāng)前年的天數(shù)
          while (remain_day_of_year >= year_temp)  // 判斷剩余的天數(shù)滿不滿一年的天數(shù)
          {
              p_NTP_TimeStruct->year++;
              remain_day_of_year -= year_temp;
              year_temp = NTP_Leapyearjudgment(p_NTP_TimeStruct->year) ? 366 : 365;
          }
      
      
      
          //3.計算哪一月的哪一天
          p_str = NTP_Leapyearjudgment(p_NTP_TimeStruct->year) ? leap_month_days : peace_month_days;
          remain_day_of_year++;          // 這里開始計算具體日期,remain_day_of_year為 0 時其實是 1 號,所以這里要先 +1
          while (remain_day_of_year > *(p_str + p_NTP_TimeStruct->month))
          {
              remain_day_of_year -= *(p_str + p_NTP_TimeStruct->month);
              p_NTP_TimeStruct->month++;
          }
      
          p_NTP_TimeStruct->month++;
          p_NTP_TimeStruct->date = remain_day_of_year;
      
          p_NTP_TimeStruct->week = NTP_WeekCalculate(p_NTP_TimeStruct);
      }
      
      
      
      
      
      
      
      /************************************************************************************************
      * @ 函 數(shù) 名:NTP_GetMessageTime
      * @ 功能說明:從NTP回復(fù)的報文中獲取時間
      * @ 參    數(shù):p_Message_Buf:報文緩沖區(qū)   Time_Start_Addr:報文中時間的起始位置   p_NTP_TimeStruct:時間結(jié)構(gòu)體
      * @ 返 回 值:
      ************************************************************************************************/
      static void NTP_GetMessageTime(uint8_t* p_Message_Buf, uint16_t Time_Start_Addr, NTP_TimeTypeDef *p_NTP_TimeStruct)
      {
          unsigned long long second = 0;
      
          for (uint8_t i = 0; i < 4; i++)
          {
              second = (second << 8) | p_Message_Buf[Time_Start_Addr + i];
          }
      
          second += 8 * 3600;
      
          p_NTP_TimeStruct->time_s = second;
      }
      
      
      
      
      
      
      int main()
      {
          WSADATA WSAData;
          SOCKET client_socket;             //客戶端的Socket
          SOCKADDR_IN server_addr;           //服務(wù)器的地址數(shù)據(jù)結(jié)構(gòu)
          SOCKADDR_IN sock;
      
          
      
          uint8_t  send_buf[BUFFER_SIZE]; //發(fā)送數(shù)據(jù)的緩沖區(qū)
          uint8_t  rece_buf[BUFFER_SIZE]; //接受數(shù)據(jù)的緩沖區(qū)
      
      
          NTP_TimeTypeDef NTP_TimeStruct;
      
      
          if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
          {
              printf("初始化失敗!");
              return -1;
          }
      
      
          //創(chuàng)建客戶端的Socket
          client_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//創(chuàng)建客戶端的Socket
          if (client_socket == INVALID_SOCKET)
          {
              printf("創(chuàng)建套接字失敗!");
          }
      
      
          /* 設(shè)置阻塞超時 */
          struct timeval timeOut;
          timeOut.tv_sec = 5;                 //設(shè)置5s超時
          timeOut.tv_usec = 0;
          if (setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0)
          {
              printf("time out setting failed\n");
          }
      
      
      
          //配置服務(wù)器的IP地址和端口號
          memset(&server_addr, 0, sizeof(server_addr));
          server_addr.sin_family = AF_INET;
          server_addr.sin_port = htons(123);//端口號為4567
          server_addr.sin_addr.s_addr = inet_addr("120.25.108.11");   //127.0.0.1為本電腦IP地址
      
      
      
          int len = sizeof(sock);
      
          while (1)
          {
              uint8_t message_buf[48] = { 0 };
      
              memset(&rece_buf, 0, sizeof(rece_buf));
      
              NTP_GenerateReqMessage(message_buf);
      
              sendto(client_socket, message_buf, sizeof(message_buf), 0, (SOCKADDR*)&server_addr, sizeof(SOCKADDR));
      
              int recv_len = recvfrom(client_socket, rece_buf, sizeof(rece_buf), 0, (SOCKADDR*)&sock, &len);
      
      
              if (recv_len >= 48)//接收到服務(wù)器返回的數(shù)據(jù)
              {
                  for (int i = 0; i < recv_len; i++)
                  {
                      printf("%02x ", rece_buf[i]);
                  }
                  printf("\r\n");
                  printf("\r\n");
      
      
                  NTP_GetMessageTime(rece_buf, 40, &NTP_TimeStruct);        //從回復(fù)的報文中獲取時間,回復(fù)數(shù)據(jù)包中時間的首地址為40
                  NTP_TimeStampToDate(NTP_TimeStruct.time_s, &NTP_TimeStruct); //由UTC時間計算日期
      
                  unsigned int time_temp = NTP_DateToTimeStamp(&NTP_TimeStruct);
      
      
                  printf("%04d-%02d-%02dT%02d:%02d:%02d", NTP_TimeStruct.year, NTP_TimeStruct.month, NTP_TimeStruct.date, NTP_TimeStruct.hour, NTP_TimeStruct.minute, NTP_TimeStruct.second);
                  printf("\r\n");
                  printf("\r\n");
      
                  printf("%u", time_temp);
                  printf("\r\n");
                  printf("\r\n");
              }
      
      
      
      
              Sleep(5000);
      
      
          }
          closesocket(client_socket);
          WSACleanup();
      
      
          return 0;
      }

       

       

       

       

       

      posted @ 2021-02-04 14:42  孤情劍客  閱讀(1806)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美激情一区二区三区成人 | 视频二区国产精品职场同事| 国产精品一区二区三区日韩| 欧美激情内射喷水高潮| 国产免费无遮挡吸奶头视频 | 国产成人亚洲精品狼色在线| 亚洲一区久久蜜臀av| 成人午夜看黄在线尤物成人| 中文字幕无码中文字幕有码a| 日韩中文字幕高清有码| 午夜在线欧美蜜桃| 亚洲av无码国产在丝袜线观看| 亚洲精品久久久久久无码色欲四季 | 日韩精品亚洲精品第一页| 热久久这里只有精品99| 国产亚洲精品第一综合| 强奷乱码中文字幕| 精品人妻中文字幕在线| 亚洲日韩av无码中文字幕美国 | 午夜男女爽爽影院免费视频下载| 国产视色精品亚洲一区二区| 亚洲精品沙发午睡系列| 欧美偷窥清纯综合图区| 青草99在线免费观看| 18禁无遮挡啪啪无码网站破解版| 无码人妻视频一区二区三区| 亚洲综合精品第一页| 亚洲 日韩 在线精品| 国产精品一区在线蜜臀| 亚洲av午夜福利大精品| 久久男人av资源站| 一区二区三区日本久久九| 性欧洲大肥性欧洲大肥女| 熟女在线视频一区二区三区| 亚洲人成网站色7799| 久久精品国产99麻豆蜜月| 婷婷久久综合九色综合88| 国产精品成人中文字幕| 亚洲全乱码精品一区二区| 免费国产一级特黄aa大片在线| 国产成人无码AV片在线观看不卡 |