(これは Marzullo のアルゴリズムではありません。複数のソースを使用して本当に正確な時刻を取得するために、上位層のサーバーでのみ使用されます。これは、通常のクライアントが 1 つのサーバーのみを使用して時刻を取得する方法です)
まず、NTP タイムスタンプは 1900 年 1 月 1 日からの秒数として保存されます。秒数は 32 ビット、秒未満は 32 ビットです。
同期は難しいです。クライアントは、リクエストを送信するときにタイムスタンプ (たとえば A) を保存します (これらの値はすべて秒単位です)。サーバーは、パケットを受信した「真の」時刻 (X を呼び出します) と、パケットを送信する「真の」時刻 (Y) からなる応答を送信します。クライアントはそのパケットを受信し、それを受信した時刻をログに記録します (B)。
NTP は、ネットワーク上で費やされる時間が送信と受信で同じであると想定します。健全なネットワーク上で十分な間隔を置いて、平均するとそうなるはずです。リクエストの送信からレスポンスの受信までの合計通過時間は BA 秒であることがわかっています。サーバーがリクエストの処理に費やした時間 (YX) を取り除き、ネットワーク トラバーサル時間だけを残したいので、BA-(YX) です。ネットワーク トラバーサル時間が対称であると想定しているため、サーバーからクライアントへの応答にかかる時間は [BA-(YX)]/2 です。したがって、サーバーが時間 Y に応答を送信し、その応答が届くまでに [BA-(YX)]/2 秒かかったことがわかります。
したがって、応答を受信した実際の時間は Y+[BA-(YX)]/2 秒です。これが NTP の仕組みです。
例 (計算を簡単にするために秒単位で):
- クライアントが「間違った」時間にリクエストを送信する 100. A=100.
- サーバーは「真の」時間 150 で要求を受信します。X=150。
- サーバーは遅いため、「真の」時刻 160 まで応答を送信しません。Y=160.
- クライアントは「間違った」時間 120 に要求を受け取ります。B=120。
- クライアントは、ネットワークに費やす時間を BA-(YX)=120-100-(160-150)=10 秒と判断します
- クライアントは、サーバーからクライアントへの応答にかかった時間を 10/2=5 秒と想定します。
- クライアントは、サーバーが応答を送信した「真の」時間にその時間を追加して、「真の」時間 165 秒で応答を受信したと推定します。
- クライアントは、クロックに 45 秒を追加する必要があることを認識しました。
適切な実装では、クライアントは常にデーモンとして実行されます。多くのサンプルを長時間にわたって使用すると、NTP はコンピュータのクロックが遅いか速いかを実際に判断し、それに応じて自動的に調整することができます。これにより、後でネットワークから切断された場合でも、適切な時間を維持できます。サーバーからの応答を平均化し、より複雑な考え方を適用することで、信じられないほど正確な時間を取得できます。
もちろん、適切な実装にはそれ以上のことがありますが、それが要点です。