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();