利用java客户端研究NTP

NTP授时原理:

客户端使用上述四个时间戳参数(T1、T2、T3、T4)来计算两个关键参数:
NTP报文从客户端到服务器的往返延迟(Delay):Delay = (T4 - T1) - (T3 - T2)
客户端与服务端之间的时间差(Offset):Offset = ((T2 - T1) + (T3 - T4)) / 2

        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.8.0</version> <!-- 请检查最新版本 -->
        </dependency>
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
import org.apache.commons.net.ntp.TimeStamp;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

public class NTPClient {
    public static void main(String[] args) throws InterruptedException {
        for(int i = 0;i<10;i++){
            Thread.sleep(1000);
        try {
            NTPUDPClient timeClient = new NTPUDPClient();
            //String ntpServer = "130.149.17.21";
            String ntpServer = "pool.ntp.org";
            InetAddress inetAddress = InetAddress.getByName(ntpServer);
            timeClient.open();
            timeClient.setVersion(3);
            timeClient.setDefaultTimeout(3000); // 设置超时时间(毫秒)
            TimeInfo timeInfo = timeClient.getTime(inetAddress);

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

            //取时间
            TimeStamp OriginateTimeStamp = timeInfo.getMessage().getOriginateTimeStamp();//报文到达服务器的时间戳 t0 (图中T1)
            TimeStamp ReceiveTimeStamp = timeInfo.getMessage().getReceiveTimeStamp();//服务器发送应答报文的时间戳 t1(图中T2)
            TimeStamp TransmitTimeStamp = timeInfo.getMessage().getTransmitTimeStamp();//报文离开客户端的时间戳 t2(图中T3)


            long t0 = OriginateTimeStamp.getTime();
            long t1 = ReceiveTimeStamp.getTime();
            long t2 = TransmitTimeStamp.getTime();

            long ntpTime0 = OriginateTimeStamp.getTime();
            Date ntpDate0 = new Date(ntpTime0);
            String formattedDate0 = dateFormat.format(ntpDate0);
            System.out.println("t0: " + formattedDate0);

            long ntpTime1 = ReceiveTimeStamp.getTime();
            Date ntpDate1 = new Date(ntpTime1);
            String formattedDate1 = dateFormat.format(ntpDate1);
            System.out.println("t1: " + formattedDate1);

            long ntpTime2 = TransmitTimeStamp.getTime();
            Date ntpDate2 = new Date(ntpTime2);
            String formattedDate2 = dateFormat.format(ntpDate2);
            System.out.println("t2: " + formattedDate2);

            //long ntpTime3 = OriginateTimeStamp.getTime();  // OriginateTimeStamp是服务器端获得授时的最新时刻
            //Date ntpDate3 = new Date(ntpTime3);
            long t3 = System.currentTimeMillis();
            String formattedDate3 = dateFormat.format(t3);
            System.out.println("t3: " + formattedDate3);

            System.out.println("delay:" +(t1-t0+t3-t2)/2);
            System.out.println("Offset:" +(t1-t0+t2-t3)/2);  // 计算的Offset

            long now = (t2+((t1-t0+t2-t3)/2));    // now的时间戳取 当前(时间 + Offset)
            System.out.println("now: " +now);

            long now2 = t3;  //本机系统时间
            System.out.println("now2:"+now2);

            System.out.println("本机系统时间与计算得到的授时时间Offset"+(now2 - now));
            timeClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        }
    }
}

参考资料:

1、NTP 剖析 - 知乎

2、正确理解NTP报文中的四个时间-优快云博客

3、数据包捕获!网络时间协议(NTP)讲解_ntp数据包-优快云博客

4、时间同步协议NTP-原理和实践_ntpv3协议-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值