e-Wordsによると、コンピュータの内部時計を、ネットワークを介して正しく調整するプロトコル。 階層構造を持ち、最上位のサーバが GPS等を利用して正しい時刻を得、 下位のホストはそれを参照する事で時刻を合わせる。
とある。要するに時計合わせ用プロトコルというなんとも地味なプロトコルだが、ちゃんとRFC868として定められているし、国内だけでも10を越えるNTPサーバが存在しているというれっきとしたプロトコルである。が、そもそもの制定の経緯が、One motivation arises from the fact that not all systems have a date/time clock, and all are subject to occasional human or machine error.
(日本語訳:日時を保持する時計が無いシステムの存在や、時計があってもその時刻は人間や機械によって適当に合わせられているという事実が Time Protocol を定める動機になった。
)とあるように、やっぱり地味路線致し方なしといった感じのプロトコルである。ちなみにサーバから得られる時刻は1900/01/01(Mon)00:00:00からサーバ呼び出し時までの秒数である。
一般にプロトコルというものはRFCの記述どおりにやれば一応使えるものである。RFC868にはTCP、UDPのどちらを使っても良し、と書いてある。以下にNTP使用の大まかな流れを示す。(S:はサーバの動作、U:はユーザ(?)の動作)
TCP | UDP |
S: 37番ポートへの接続要求をlistenする ↓ U: 37番ポートへ接続する ↓ S: 32bitのバイナリデータとして、時刻情報を送信する ↓ U: 時刻情報を受信する ↓ U: 接続を閉じる ↓ S: 接続を閉じる |
S: 37番ポートへの接続要求をlistenする ↓ U: 37番ポートへ空のデータグラムを送信する ↓ S: 空のデータグラムを受信する ↓ S: 時刻情報を32bitのバイナリデータとしてダイアグラムに入れて送信する ↓ U: 時刻情報の入ったデータグラムを受け取る |
今回はWinsock Ver.2.0を使用し、TCP接続でNTPを取り扱う。と、いうことで、簡単なコーディングの流れは上記の表と照らし合わせて、以下のようになる。
具体的に、ということで余計な講釈はたれず、ソースを見ていただくことにしよう。その方が啓発的な理解にも繋がりますからな(´ー`y (重要な部分は色を変えて示しています)#ちなみに使用言語はC++(開発環境はVisualC++6.0)
|
|
Winsockの初期化をコンストラクタ、Winsockの後始末をデストラクタ、そしてソケットの初期化〜ソケットの後始末をint FCNTP::GetDataFromServer(unsigned long *pulTime, const char *strServerIP)
で行っています。非常に簡単なクラスで、通信用の関数に食われる時間は考慮してませんが、ちょっとしたテストに供するには問題ないと思います。ちなみに使用例は以下の通り。
|