web-dev-qa-db-ja.com

Java NTPクライアント

ローカルクロックオフセットを決定するためにNTPサーバーと通信するソフトウェアが必要です。org.Apache.commons.net.ntpパッケージを使用しようとしましたが、実行時の実装がかなり貧弱です。 Windowsでは、System.currentTimeMillis()を使用してNTPパケット交換の前後の時間を決定するため。ご存知かもしれませんが、この値はシステムが更新されたときにのみ更新されます。最新のWin2k3サーバーでは64Hzまたは15.625msごとのクロックティック。これにより、クロックオフセット計算の精度が大幅に制限されます。

Ntpdは、CPU高周波タイマーを使用して、システムクロックティック間を補間し、はるかに高い解決時間を実現します。これまたは同様の手法を使用するJava実装を知っていますか?またはApache以外の他のNTP実装を知っていますか?

19
Matt Howells

NTP Java実装が support.ntp.org

10
dfa

この質問はGoogleで「Java NTPクライアント」のランクが非常に高いため:

Androidには、シンプルなNTPクライアント: Android.net.SntpClient のコンパクトなApacheライセンスの実装があります。

Android以外のJavaで実行するには変更する必要がありますが、コードは約100行のコードとさらに100行の詳細なコメントであり、Androidシステムクロック-そして偶然にも、nanoTime()のような相対タイマーを受け入れる準備ができています。これは、すでにそのような相対タイマーを使用しているためです。

10
Jan Schejbal

Java 5以上を使用している場合、 System.nanoTime() を使用してタイムオフセットのより正確な測定を実行できますか?変更する必要があります既存のNTPコードですが、ソースが必要です。これが難しいとは思いません。

3
Brian Agnew

私はあなたが使用できるJava実装(Java 7)を書きました: SntpClient

3
user2179737

これは古い質問ですが、すべての回答がこれらのライブラリの使用方法を説明しているわけではないことに気付きました。この回答では、基本的な実装とその背後にあるロジックを示します。

それを実装する簡単な方法は、 Apache Commons Netライブラリ を使用することです。このライブラリは、コネクションレス型NTPリクエストを管理し、NTPUDPClientインスタンスを返すために、TimeInfoクラスを提供します。このインスタンスは、システムの時間と=の間のオフセットを計算する必要があります。 NTPサーバーの時間。ここで実装してみましょう:

  1. Apache Commons Netライブラリ をプロジェクトに追加します。
_<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
_
0
Teocci