协议有了,那么java有没有相关实现呢。当然也有了。apache的commons-net包下面有ntp的实现。主要的类是:
和
看下用法,NTPUDPClient中有方法:
和
第二个重载方法是用协议规范默认端口:123。
看下具体实现代码:
大概过程就是想目标网络地址发包来获取网络时间,具体细节由协议来规范。
所以我们还需要来确定网络地址,继续搜索,发现网络上有时间服务器,也叫授时服务器。我们的用智能手机的时间是不是通过这种方式来同步的呢?
找到了这样一些服务器地址:
中国时间网
国外的
NIST Internet Time Servers
代码例子:
输出:
可调整本机时间,然后观察输出是否正确。
- 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 <i>TimeInfo</i>
- * object that allows access to all the fields of the NTP message header.
- * <p>
- * @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;
- }
大概过程就是想目标网络地址发包来获取网络时间,具体细节由协议来规范。
所以我们还需要来确定网络地址,继续搜索,发现网络上有时间服务器,也叫授时服务器。我们的用智能手机的时间是不是通过这种方式来同步的呢?
找到了这样一些服务器地址:
中国时间网
国外的
NIST Internet Time Servers
代码例子:
- 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-02 11:01:08
可调整本机时间,然后观察输出是否正确。