【问题标题】:Java NTP clientJava NTP 客户端
【发布时间】:2010-10-29 20:08:02
【问题描述】:

我需要我的软件与 NTP 服务器通信以确定本地时钟偏移。我曾尝试使用 org.apache.commons.net.ntp 包,但在 Windows 上运行时它的实现相当差,因为使用 System.currentTimeMillis() 来确定 NTP 数据包交换前后的时间。你可能知道也可能不知道,这个值只在系统时钟滴答声时更新,在大多数现代 Win2k3 服务器上是 64Hz 或每 15.625ms。这极大地限制了时钟偏移计算的准确性。

Ntpd 使用 CPU 高频定时器在系统时钟节拍之间进行插值,并获得更高的分辨率时间。您知道使用这种技术或类似技术的 Java 实现吗?或者您知道除 Apache 之外的任何其他 NTP 实现吗?

【问题讨论】:

  • 不能向 Apache Commons 库提交补丁吗?
  • 如果有时间实施和测试它,以及我的公司霸主的意愿,是的,我可以。
  • 我在 Software Recommendations Stack Exchange 上询问了 a similar Question

标签: java ntp


【解决方案1】:

support.ntp.org 上有一个 NTP Java 实现

【讨论】:

  • 唉,它是 SNTP 的幼稚实现。但是 +1 找到它,谢谢。
【解决方案2】:

因为这个问题在 Google 上的“Java NTP 客户端”排名很高:

Android 有一个简单 NTP 客户端的漂亮、紧凑的 Apache 许可实现:android.net.SntpClient

需要修改它才能在非 Android java 上运行,但这应该是微不足道的,因为代码大约是 100 行代码加上另外 100 行详细的 cmets,除了 Android 系统时钟之外没有外部依赖项 -偶然地,它已经准备好接受像nanoTime() 这样的相对计时器,因为它已经使用了这样的相对计时器。

【讨论】:

  • 如何替换SystemClock.elapsedRealtime();
  • SntpClient@hide 注释,所以我们不能(干净地)使用它。
  • @KevinRobatel 这个想法不是直接使用它;我提到许可证的原因是您可以包含它的私有“分叉”副本(调整包名称,以及您需要的任何其他更改,例如不同的计时器)。这就是我不得不使用它时采取的方法。
【解决方案3】:

我写了一个你可以使用的java实现(Java 7):SntpClient

【讨论】:

    【解决方案4】:

    如果您使用的是 Java 5 或更高版本,您可以使用System.nanoTime() 来执行更准确的时间偏移测量吗?您必须修改现有的 NTP 代码,但您应该有它的源代码,我不认为这会很困难。

    【讨论】:

    • 是的,System.nanoTime() 访问高频计时器,我希望这将用于在一个不错的 Java NTP 实现中添加时间戳。然而,这并不重要,所以我希望其他人已经完成并调试了它。
    • 是的。我找不到任何明显的实现。一个名利双收的机会,也许吧? :-)
    • System.nanoTime() 只能用于测量经过的时间,并且与系统或挂钟时间的任何其他概念无关,因此不能用于将本地系统时间与绝对时间进行比较NTP 服务器。
    • 它可用于计算任何时刻的时间,给定NTP时间从前一时刻和使用System.nanoTime()计算的两个时刻之间的经过时间
    【解决方案5】:

    我知道这是一个老问题,但我注意到所有答案都没有解释如何使用这些库。在这个答案中,我们将展示一个基本的实现及其背后的逻辑。

    实现它的一种简单方法是使用Apache Commons Net library。这个库将提供一个NTPUDPClient 类来管理无连接的NTP 请求并返回一个TimeInfo 实例。此实例应计算系统时间和 NTP 服务器时间之间的偏移量。让我们尝试在这里实现它:

    1. Apache Commons Net library 添加到您的项目中。
    <dependency>
      <groupId>commons-net</groupId>
      <artifactId>commons-net</artifactId>
      <version>3.6</version>
    </dependency>
    
    1. 创建NTPUDPClient 类的新实例。
    2. 设置默认超时和 NTP 服务器的InetAddress
    3. 调用NTPUDPClient.getTime() 方法从指定服务器检索具有时间信息的TimeInfo 实例。
    4. 调用computeDetails()方法计算和验证NTP消息包的细节。
    5. 最后,获取offset 并计算原子时间。

    这里我们有一个基本的实现:

    import java.net.InetAddress;
    import java.util.Date;
    import org.apache.commons.net.ntp.NTPUDPClient; 
    import org.apache.commons.net.ntp.TimeInfo;
    
    public class NTPClient {
      private static final String SERVER_NAME = "pool.ntp.org";
    
      private volatile TimeInfo timeInfo;
      private volatile Long offset;
    
      public static void main() throws Exception {
    
        NTPUDPClient client = new NTPUDPClient();
        // We want to timeout if a response takes longer than 10 seconds
        client.setDefaultTimeout(10_000);
    
        InetAddress inetAddress = InetAddress.getByName(SERVER_NAME);
        TimeInfo timeInfo = client.getTime(inetAddress);
        timeInfo.computeDetails();
        if (timeInfo.getOffset() != null) {
            this.timeInfo = timeInfo;
            this.offset = timeInfo.getOffset();
        }
    
        // This system NTP time
        TimeStamp systemNtpTime = TimeStamp.getCurrentTime();
        System.out.println("System time:\t" + systemNtpTime + "  " + systemNtpTime.toDateString());
    
        // Calculate the remote server NTP time
        long currentTime = System.currentTimeMillis();
        TimeStamp atomicNtpTime = TimeStamp.getNtpTime(currentTime + offset).getTime()
    
        System.out.println("Atomic time:\t" + atomicNtpTime + "  " + atomicNtpTime.toDateString());
      }
    
      public boolean isComputed()
      {
        return timeInfo != null && offset != null;
      }
    }
    

    你会得到类似的东西:

    System time:    dfaa2c15.2083126e  Thu, Nov 29 2018 18:12:53.127
    Atomic time:    dfaa2c15.210624dd  Thu, Nov 29 2018 18:12:53.129
    

    【讨论】:

    • 它对我有用,在我的情况下,我需要今天来自服务器而不是来自系统的日期。如果有人更改系统时间,我的代码将失败。这段代码对我来说很棒。
    猜你喜欢
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2012-06-01
    • 2017-08-04
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    相关资源
    最近更新 更多