博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java获取NTP网络时间
阅读量:5234 次
发布时间:2019-06-14

本文共 3326 字,大约阅读时间需要 11 分钟。

 最近项目中涉及到一个时间验证的问题,需要根据当前时间来验证业务数据是否过期。所以直接写代码如下:

         new java.util.Date().getTime();  
        结果测试的时候出现了问题,怎么验证都是过期。后来发现是服务器主机时间不对。也就是说如果服务器时间不准确或者被篡改,那么验证这部分会出现问题。所以决定采用获取网络当前时间来代替获取系统当前时间
        搜索了一下,原来获取网络时间有一个协议:(NTP: 网络时间协议 )。 
        协议有了,那么java有没有相关实现呢。当然也有了。apache的commons-net包下面有ntp的实现。主要的类是: 

              org.apache.commons.net.ntp.NTPUDPClient               org.apache.commons.net.ntp.TimeInfo 
看下用法,NTPUDPClient中有方法: 
        public TimeInfo getTime(InetAddress host, int port) throws IOException 

          public TimeInfo getTime(InetAddress host) throws IOException 


第二个重载方法是用协议规范默认端口:123。 

看下具体实现代码: 

/***     * Retrieves the time information from the specified server and port and     * returns it. The time is the number of miliiseconds since     * 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.     * This method reads the raw NTP packet and constructs a TimeInfo     * object that allows access to all the fields of the NTP message header.     * 

* @param host The address of the server. * @param port The port of the service. * @return The time value retrieved from the server. * @exception IOException If an error occurs while retrieving the time. ***/ public TimeInfo getTime(InetAddress host, int port) throws IOException { // if not connected then open to next available UDP port if (!isOpen()) { open(); } NtpV3Packet message = new NtpV3Impl(); message.setMode(NtpV3Packet.MODE_CLIENT); message.setVersion(_version); DatagramPacket sendPacket = message.getDatagramPacket(); sendPacket.setAddress(host); sendPacket.setPort(port); NtpV3Packet recMessage = new NtpV3Impl(); DatagramPacket receivePacket = recMessage.getDatagramPacket(); /* * Must minimize the time between getting the current time, * timestamping the packet, and sending it out which * introduces an error in the delay time. * No extraneous logging and initializations here !!! */ TimeStamp now = TimeStamp.getCurrentTime(); // Note that if you do not set the transmit time field then originating time // in server response is all 0's which is "Thu Feb 07 01:28:16 EST 2036". message.setTransmitTime(now); _socket_.send(sendPacket); _socket_.receive(receivePacket); long returnTime = System.currentTimeMillis(); // create TimeInfo message container but don't pre-compute the details yet TimeInfo info = new TimeInfo(recMessage, returnTime, false); return info; }

大概过程就是想目标网络地址发包来获取网络时间,具体细节由协议来规范。 
所以我们还需要来确定网络地址,继续搜索,发现网络上有时间服务器,也叫授时服务器。我们的用智能手机的时间是不是通过这种方式来同步的呢? 
       找到了这样一些服务器地址: 
 
       国外的 
 

代码例子: 

public static void main(String[] args) {		try {			NTPUDPClient timeClient = new NTPUDPClient();			String timeServerUrl = "time-a.nist.gov";			InetAddress timeServerAddress = InetAddress.getByName(timeServerUrl);			TimeInfo timeInfo = timeClient.getTime(timeServerAddress);			TimeStamp timeStamp = timeInfo.getMessage().getTransmitTimeStamp();			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");			System.out.println(dateFormat.format(timeStamp.getDate()));		} catch (UnknownHostException e) {			e.printStackTrace();		} catch (IOException e) {			e.printStackTrace();		}	}

  输出:2013-04-0211:01:08  

 

转载于:https://www.cnblogs.com/arnoid/p/3208809.html

你可能感兴趣的文章
熟用TableView
查看>>
IO模型《六》IO模型比较分析
查看>>
Android 博客园客户端 (七)登录功能
查看>>
PHP动态页面 生产静态页 方法二
查看>>
NSOperation 代码,阐述NSOperation一般功能和重要功能
查看>>
androidstudio 2.3.3 jni过程汇总(2):2、使用so文件
查看>>
第二篇:使用Spark对MovieLens的特征进行提取
查看>>
WPF 依赖项属性[DependencyProperty]Text的绑定方式
查看>>
在Visual Studio中使用VueJS时,不可以用 v-bind 的简写 : 及 v-on的简写 @
查看>>
并查集--学习详解
查看>>
[App Store Connect帮助]八、维护您的 App(6)使某个先前版本不可下载
查看>>
[Swift]LeetCode419. 甲板上的战舰 | Battleships in a Board
查看>>
《将博客搬至CSDN》
查看>>
JavaEE笔记(二)
查看>>
Java大数——a^b + b^a
查看>>
zcmu 1041
查看>>
《网络攻防》网络欺诈技术防范
查看>>
[Angular] USING ZONES IN ANGULAR FOR BETTER PERFORMANCE
查看>>
[React] Create component variations in React with styled-components and "extend"
查看>>
Centos下Python添加RSA模块
查看>>