0

RFC868準拠のタイムサーバーと時刻を同期するための概念実証を示すサンプルアプリケーションを作成しようとしています。

これまでのところ、Java Socket APIを使用して、サーバーに接続してクエリを実行し、サーバーから応答を取得することはできますが、人間が読める形式ではありません。

私が得�)6た応答は次のとおりです。応答はバイナリ形式で送信されていると思います(ただし、わかりません)。RFC868はそれを言いSend the time as a 32 bit binary numberます。

私の質問は次のとおりです。

  1. この応答を解析するにはどうすればよいですか?
  2. 私のこのアプローチとは別に、これを達成するために私が取るべき他の推奨されるアプローチがあるかどうか知りたいです。

前もって感謝します。

4

2 に答える 2

2

1)この応答を解析するにはどうすればよいですか?

ApacheCommonsNetライブラリからTimeTCPClientのソースコードを確認してください。

public long getTime() throws IOException {
  DataInputStream input;
  input = new DataInputStream(_input_);
  return (input.readInt() & 0xffffffffL);
}

public Date getDate() throws IOException {
  return new Date((getTime() - SECONDS_1900_TO_1970)*1000L);
}

2)私のこのアプローチとは別に、これを達成するために私が取るべき他の推奨されるアプローチがあるかどうか知りたいです。

Apache Commons Net Libraryを使用して、TimeTCPClientのAPIを確認してください。

Apache Commons Netホームページ、これがお役に立てば幸いです。

于 2012-04-06T11:32:06.900 に答える
2

RFCに記載されているように、これは1900-01-01T00:00:00からの秒数です。Javaの場合は、これをLongに変換し、基準日を1970-01-01T00:00:00に変更し、1000を掛けて日付を取得します。次に、この値を使用して新しい日付を作成できます。

ソケット入力ストリームをDataInputStreamにラップし、rfsOffsetに読み込みます(定数を使用しました)。次に、次のようなことを行うことができます。

int rfcOffset = -752253627; // Fri Apr 06 11:00:32 EDT 2012
// Current offsets will be negative convert to long positive value
long offsetSecs = rfcOffset + 4294967296L; 
System.out.println(offsetSecs);
// Adjust time base from 1900 to 1970 and convert to millis
long offsetMillis = ( offsetSecs - 2208988800L)* 1000L; 
System.out.println(offsetMillis);
Date rfcDate = new Date(offsetMillis);
System.out.println(rfcDate.toString());

注:これは2036年までしか機能せず、時間は数ミリ秒ずれます。

編集:RFC 868は古いプロトコルであり、同期に適したタイムソースとは見なされなくなりました。適切なタイムソースはNTPを使用し、正しい秒を返します。数ミリ秒ずれている場合がありますが、通常は10ミリ秒以内で正確です。多くのハードウェアクロックは大幅にドリフトし、クロックが不正確なシステムからの大幅なドリフトを確認しました(NTPが実行されている場合でも)。NTPはドリフトクロックを修正しますが、必要なシフトを決定するのに数分かかります。

EDIT2:RFC 868は古いものですが、バックグラウンドプロセスを必要とせずに、携帯電話の時刻を最も近い秒に設定するだけで十分な場合があります。携帯電話がプロバイダーから送信された信号と同期できる場合、これは必要ありません。

于 2012-04-06T15:17:47.113 に答える