iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
自我挑戰組

WiFiBoy Python 玩學機介紹系列 第 22

22. NTP時間伺服器對時

  • 分享至 

  • xImage
  •  

時間記錄的重要性

現今上班族與學生人手一支手機,無時無刻不忘滑兩下。2000年以後出生的朋友,基本上都在網路的世界中成長。網路就像是水電這樣的基本設施,但各位有沒有想過更基礎更重要的一項基礎建設?那就是時間對時服務。不知道各位有沒有一個經驗,就是電腦時間跑掉,會有很多奇怪的問題產生。最活生生的例子是:

https://ithelp.ithome.com.tw/upload/images/20230923/20105707iVDY3MiSHM.png

電腦時鐘部會隨便壞掉,頂多就是主機板上的電池沒電,換個電池,設定一下時間就能解決此問題。

為什麼正確的時間是很重要的設定,HTTPS 的網站憑證是經由憑證機構所簽發的,而產生這個憑證所需的加密技術要由亂數產生,而電腦的亂數產生器,則是由特定演算法搭配時間參數所計算出來。因此,如果您的設備時間很明顯的就跟憑證產生的時間有很大的差異,自然就會被系統判定為憑證失效的狀況,自然就無法連上 HTTPS 服務的網頁。

何謂 NTP 服務?

根據「國家時間與頻率標準實驗室」的網頁介紹,NTP(Network Time Protocol) 是1985 年由德拉瓦大學的D.L. Mills教授提出。可以估算封包在網路上的往返延遲外,還可獨立地估算電腦時鐘偏差,達到在網路上實現高精準度電腦校時的目的。

https://ithelp.ithome.com.tw/upload/images/20230923/20105707ry6tiEhsi3.png

很多嵌入式的設備其實是沒有內建時鐘模組,想要做一些網路的應用,「對時」這件事情就是件很重要的基礎工作。設備的時間差太多,就會有許多問題會產生。舉個例子,試想你是網路系統管理員,你要追蹤異常的登入使用紀錄,如果Server A 和 Server B的時間有明顯的差異(例如差了三十分鐘),請問您要如何排列出使用者登入主機、存取檔案的正確先後順序呢?

所以,當我們要把玩學機也加入到內網網路進行工作,就需要先讓玩學機有辦法跟國家時間頻率標準實驗室的 NTP 主機對時。這樣未來玩學機上的系統紀錄時間,就會變得可以信任。請先記下這個公開 NTP Server ,待會的程式會用到。

time.stdtime.gov.tw

玩學機NTP 伺服器對時實驗

開始對時之前,請先執行下列程式,確認 MicroPython 預設的系統時間。

>>> import ntptime
>>> time.localtime()
(2000, 1, 1, 0, 0, 6, 5, 1)

我們可以了解,MicroPython 硬體啟動時,是從 2000/01/01 開始計算時間。

我們來做一個簡單實驗,步驟如下:

  1. 先連線到家裡的無線網路基地台,取得連上網際網路的能力。
  2. 進行 NTP 對時。
  3. 對時成功後,建立一個output.txt,寫入到玩學機的FLASH 空間。
  4. 開啟檔案,確認寫入的時間戳記是正確的。
# NTP 對時
# 1. 先連線到家裡的無線網路基地台,取得連上網際網路的能力。
# 2. 進行 NTP 對時。
# 3. 對時成功後,建立一個output.txt,寫入到玩學機的FLASH 空間。
# 4. 開啟檔案,確認寫入的時間戳記是正確的。
# 無線網路連線
WiFi_SSID = 'ESP32AP'
WiFi_PASSWORD = '12345678@'
def WiFi_connect(WiFi_SSID, WiFi_PASSWORD):
    import network
    sta_if = network.WLAN(network.STA_IF)
    print(sta_if.ifconfig())
    if not sta_if.isconnected():
        sta_if.active(True)
        sta_if.connect(WiFi_SSID, WiFi_PASSWORD)
        print(sta_if.ifconfig())
        while not sta_if.isconnected(): pass
WiFi_connect(WiFi_SSID, WiFi_PASSWORD)

import ntptime
# 透過網路上的 NTP 國際時鐘服務,可以取得準確的現在時間。
ntptime.settime() # 取得 NTP 網路時間,並設定系統時鐘
# time.localtime() # 從此可以用 time.localtime() 取得現在時間
mySystemTime = time.localtime(time.time()+28800) # 台灣時間的 GMT+8 算法,位移 8*60*60 秒
# (2023, 9, 23, 18, 24, 59, 5, 266)
# 2023年9月23日,18時24分59秒,星期五, 今年第 266 天

# 寫入測試檔案
with open('output.txt', 'w') as fd:
  fd.write('%s 年 %s 月 %s 日' % (mySystemTime[0], mySystemTime[1], mySystemTime[2]))

fd.close()

上一篇
21. 無線網路連線
下一篇
23. 簡易 Web Server
系列文
WiFiBoy Python 玩學機介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言