SNTP获取时间源统一时间

时间记录:2019-9-30
最近在进行时间戳的服务的阅读的时候发现了我们通常会使用一个公用的时间源作为一个标准的时间,我们知道在windows中有一个网络时间同步的功能那里使用的同步的时间源就是基于一种协议的网络的时间的请求。通常在作为网络的时间机器的时间的依据是一个量子时间钟,这个时间的误差在2000万年的误差很小。我们不做研究在这里,我们这里主要了解下时间的网络的协议的格式以及数据的传输的方式,在进行获取网络时间的时候如何进行网络的时间的获取(这里以java的方式来进行请求)
我们首先建立自己的时间源服务,这里使用的是ntp,然后就是不同版本的rfc的协议的格式,然后就是在java下如何进行时间的获取(其实只要了解其的网络的协议的格式就可以了,不仅仅是局限于语言)
搭建自己的时间源
环境描述:我这里是基于虚拟机的操作
安装

yum install ntp

配置ntp

vi /etc/ntp.conf
找到service,添加自己的地址127.0.0.1,将其余的上游注释,也可以使用其余上游
我们只需要指定当前的时间源为服务的时间源,在实际的环境中通常会有多级的时间源,这里也可以进行简单的配置

时间源服务的默认端口为123
时间源的数据格式
时间源服务的协议的报文格式服从RFC标准
从下面的NtpMessage中有得知支持所有版本的NTP和SNTP
This class represents a NTP message, as specified in RFC 2030. The message format is compatible with all versions of NTP and SNTP.
协议介绍这一块不做具体的研究了,平时使用的不多,主要记录下,存在这样一个东西

java的时间数据的获取
sntp使用的是UDP的网络协议,进行数据的传输,在java中封装组合了UDP协议的DatagramSocket的api进行网络的请求。然后我们需要知道对应的网络协议的数据格式,就可以进行数据的交互,将对应的数据格式转换为自己需要的,可以理解的数据,实际上就是对一对的数据进行持久化的封装,以供自己的需求和使用,java中有现成的javasntpclient.源地址链接,我们尝试使用此项进行网络的时间源的数据的获取。其中主要的是NtpMessage的封装,为了跟方便的使用

package com.huo.time;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.DecimalFormat;


/**
 * NtpClient - an NTP client for Java.  This program connects to an NTP server
 * and prints the response to the console.
 * 
 * The local clock offset calculation is implemented according to the SNTP
 * algorithm specified in RFC 2030.  
 * 
 * Note that on windows platforms, the curent time-of-day timestamp is limited
 * to an resolution of 10ms and adversely affects the accuracy of the results.
 * 
 * 
 * This code is copyright (c) Adam Buckley 2004
 *
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public License as published by the Free 
 * Software Foundation; either version 2 of the License, or (at your option) 
 * any later version.  A HTML version of the GNU General Public License can be
 * seen at http://www.gnu.org/licenses/gpl.html
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 
 * more details.
 *  
 * @author Adam Buckley
 */
public class SntpClient
{
   
	public static void main(String[] args) throws IOException
	{
   
		String serverName = "192.168.195.128";
		
		// Process command-line args
//		if(args.length==1)
//		{
   
//			serverName = args[0];
//		}
//		else
//		{
   
//			printUsage();
//			return;
//		}
		
		// Send request
		DatagramSocket socket = new DatagramSocket();
		InetAddress address = InetAddress.getByName(serverName);
		byte[] buf = new NtpMessage().toByteArray();
		DatagramPacket packet =
			new DatagramPacket(buf, buf.length, address, 123);
		
		// Set the transmit timestamp *just* before sending the packet
		// ToDo: Does this actually improve performance or not?
		NtpMessage.encodeTimestamp(packet.getData(), 40,
			(System.currentTimeMillis()/1000.0) + 2208988800.0);
		
		socket.send(packet);
		
		
		// Get response
		System.out.println("NTP request sent, waiting for response...\n");
		packet = new DatagramPacket(buf, buf.length);
		socket.receive(packet);
		
		// Immediately record the incoming timestamp
		double destinationTimestamp =
			(System.currentTimeMillis()/1000.0) + 2208988800.0;
		
		
		// Process response
		NtpMessage msg = new NtpMessage(packet.getData());
		
		// Corrected, according to RFC2030 errata
		double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) -
			(msg.transmitTimestamp-msg.receiveTimestamp);
			
		double localClockOffset =
			((msg.receiveTimestamp - msg.originateTimestamp) +
			(msg.transmitTimestamp - destinationTimestamp)) / 2;
		
		
		// Display response
		System.out.println("NTP server: " + serverName);
		System.out.println(msg.toString());
		
		System.out.println("Dest. timestamp:     " +
			NtpMessage.timestampToString(destinationTimestamp));
		
		System.out.println("Round-trip delay: " +
			new DecimalFormat("0.00").format(roundTripDelay*1000) + " ms");
		
		System.out.println("Local clock offset: " +
			new DecimalFormat("0.00").format(localClockOffset*1000) + " ms");
		
		socket.close();
	}
	
	
	
	/**
	 * Prints usage
	 */
	static void printUsage()
	{
   
		System.out.println(
			"NtpClient - an NTP client for Java.\n" +
			"\n" +
			"This program connects to an NTP server and prints the response to the console.\n" +
			"\n" +
			"\n" +
			"Usage: java NtpClient server\n" +
			"\n" +
			"\n" +
			"This program is copyright (c) Adam Buckley 2004 and distributed
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值