NTP 是網路對時的協定,在一般因為是作業系統自動處理,所以也不知到哪裡找資訊。
反而因為 arduino 這類 MCU 興起的關係,很多老協定的原始碼與 SPEC 就有了關鍵字可以深探與學習。
重點
* UDP 傳送,48 BYTE,UTC時間
兩段重點程式
```
unsigned long sendNTPpacket(IPAddress& address) {
Serial.println("sending NTP packet...");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE); //clear the buffer
//Initialize values needed to form NTP request
//(see URL above for details on the packets)
packetBuffer[0]=0b11100011; // LI, Version, Mode
packetBuffer[1]=0; // Stratum, or type of clock
packetBuffer[2]=6; // Polling Interval
packetBuffer[3]=0xEC; // Peer Clock Precision
//8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12]=49;
packetBuffer[13]=0x4E;
packetBuffer[14]=49;
packetBuffer[15]=52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(address, 123); //NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE); //send UDP request to NTP server
udp.endPacket();
}
```
```
unsigned long getUnixTime() {
WiFi.hostByName(ntpServerName, timeServerIP); //get a random server from the pool
sendNTPpacket(timeServerIP); //send an NTP packet to a time server
delay(1000); // wait to see if a reply is available
int cb=udp.parsePacket(); //return bytes received
unsigned long unix_time=0;
if (!cb) {Serial.println("no packet yet");}
else { //received a packet, read the data from the buffer
Serial.print("packet received, length=");
Serial.println(cb); //=48
udp.read(packetBuffer, NTP_PACKET_SIZE); //read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
//or two words, long. First, esxtract the two words:
unsigned long highWord=word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord=word(packetBuffer[42], packetBuffer[43]);
//combine the four bytes (two words) into a long integer
//this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900=highWord << 16 | lowWord;
Serial.print("Seconds since Jan 1 1900=" );
Serial.println(secsSince1900);
Serial.print("Unix time=");
//Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
unix_time=secsSince1900 - 2208988800UL;
Serial.print(F("Unix time stamp (seconds since 1970-01-01)="));
Serial.println(unix_time); //print Unix time
}
return unix_time; //return seconds since 1970-01-01
}
```
參考
* [Arduino C on ESP8266 學習筆記 (三) : 從 NTP 伺服器取得網路時間](http://yhhuang1966.blogspot.com/2017/09/arduino-ide-esp8266-ntp.html)