JAVA 實現NTP Client,獲取NTP Server時間

NTP

NTP(Network Time Protocol)一般指網絡時間協議,是用來使計算機時間同步化的一種協議,它可以使計算機對其服務器或時鐘源做同步化,它可以提供高精準度的時間校正,NTP的目的是在無序的Internet環境中提供精確和健壯的時間服務。

如果想要了解更多關於NTP的知識,可以點這裏。百度百科_網絡時間協議

NTP Server

可以用Windows搭建NTP Server:

  • win + R鍵(打開運行窗口)輸入 regedit,打開註冊表。
    在這裏插入圖片描述
  • 找到[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\AnnounceFlags] AnnounceFlags 值修改爲 5,強制主機將它自身時間源宣佈爲可靠的時間源。
    在這裏插入圖片描述
  • 找到[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer]將 Enabled 修改爲 1,啓用NTPServer。
    在這裏插入圖片描述
  • 修改完註冊表之後,需要重啓一下Windows Time 服務。Win + R鍵輸入cmd,在cmd窗口裏面輸入:
//先停止
net stop w32time
//再啓動
net start w32time

運行結果截圖:
在這裏插入圖片描述

  • 由於系統防火牆的啓用,可能會導致NTP Server默認使用的123端口訪問不到,如果已經關閉防火牆了,可以跳過下面的步驟。
    打開 控制面板,查看方式選擇 小圖標,找到 Windows防火牆,點擊進入。
    在這裏插入圖片描述
    在防火牆上找到 高級設置,點擊進入。
    右鍵 入站規則 -> 新建規則,創建的規則類型選擇 端口,此規則應用於 UDP,次規則應用於 特定本地端口 內容填 123,符合指定條件時 允許連接,剩下的都點下一步,名稱可以填 NTP Server Port
    在這裏插入圖片描述
  • 到這裏,NTP Server基本已經搭建成功了,但是系統默認的Windows Time 服務是手動方式啓動 的,可以改爲自動,畢竟它是Server要保證下次服務正常啓動運行。

NTP Client

使用第三方庫:Apache Commons Net >> 3.6

maven方式:

<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.6</version>
</dependency>

gradle方式:

// https://mvnrepository.com/artifact/commons-net/commons-net
compile group: 'commons-net', name: 'commons-net', version: '3.6'

寫起來還是比較簡單的,直接上代碼:

public class NTPClient {

    private NTPUDPClient ntpudpClient = null;
    private InetAddress inetAddress = null;
    private boolean isInit = false;

    public void initNTPClient(String url, int timeout) {
       this.ntpudpClient = new NTPUDPClient();
       //設置連接超時時間
       this.ntpudpClient.setDefaultTimeout(timeout);
        try {
            this.inetAddress = InetAddress.getByName(url);
            this.isInit = true;
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public String getNTPServerTime() {
        if (this.isInit) {
            try {
                TimeInfo timeInfo = this.ntpudpClient.getTime(this.inetAddress);
                TimeStamp timeStamp = timeInfo.getMessage().getTransmitTimeStamp();
                Date date = timeStamp.getDate();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
                return simpleDateFormat.format(date);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public void stopNTPClient() {
        this.isInit = false;
        if (null != this.ntpudpClient)
            this.ntpudpClient.close();
    }

注意!一定要setDefaultTimeout(timeout),不然連接不上NTPServer的時候,整個線程都被阻塞了,至於什麼時候被喚醒,還沒測試過,反正就會一直卡着。

用法:

        NTPClient ntpClient = new NTPClient();
        ntpClient.initNTPClient("192.168.43.32", 5000);
        System.out.println(ntpClient.getNTPServerTime());
        ntpClient.stopNTPClient();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章