VC++2003 SDK(非MFC)
Windows XP Home SP2
よくフリーソフトなどの時計ソフトで NTP サーバーから自動的に
時刻を合わせる機能がありますよね。
以前、自分でも時計ソフトを作成して普段はその自作ソフトを
使っています。そこで自作の時計ソフトにも自動的に合わせる
機能を実装したいと思っています。どういう方法でネットから
パソコンの時刻を合わせるのか方法を知りたいので教えて下さい。
当方では次のリンクを見つけましたが意味が分かりません。
http://www.jitaku-server.net/first_ntp.html
こちらの情報はどう参考にすれば良いでしょうか。
解説などをお願いします。
とりあえず用語が悪いな
ネットからパソコンの、だと外部から接続して自分のマシンの時計を合わせる意味にな
る。
本当にやりたいのは、自分から外部に接続して時計を合わせる、だろう?
外から中だと、セキュリティ的に大いに問題があるので...
んで、この辺、歴史的事情ってやつがあって、話がいろいろと複雑なのだが
詳細に解説するとなると掲示板のスペースではとても足らない。
もうちょっと自力でいろいろ調たうえで、話を限定して欲しい。
まずはいつもの wikipedia でも見てみよう。
http://ja.wikipedia.org/wiki/Network_Time_Protocol
wikipedia からのリンク
http://www.atmarkit.co.jp/fwin2k/win2ktips/050nettime/nettime.html
Windows XP だったらNTPによる時刻補正やってくれるから、
わざわざアプリ側でやんなくても。
tetrapodさん、επιστημηさんへ。
アドバイスなどをありがとうございます。
>Windows XP だったらNTPによる時刻補正やってくれるから、
>わざわざアプリ側でやんなくても。
自作の時計ソフトは Windows 95、98 でも使いたいのです。
かなり古い OS ですけど。開発時の OS は XP です。
>とりあえず用語が悪いな
>ネットからパソコンの、だと外部から接続して自分のマシンの時計を合わせる意味に
なる。
本当に表現がおかしいね。指摘されて気づいたよ。
表現するならパソコンからネット接続して~合わせる。だね。
>本当にやりたいのは、自分から外部に接続して時計を合わせる、だろう?
この表現だね。
>もうちょっと自力でいろいろ調たうえで、話を限定して欲しい。
ずっと調べているんですけど。
ネット用語などの意味が良く分からなくて手間取っています。
プロトコル?って何?から1つ1つ学習しているため時間がかかるのです。
最終的には自作の時計ソフトに C 言語で定期的(自動的)に時刻修正する機能を
組み込みたいのです。つまり、Windows XP で標準である「インターネット時刻」
タブと同じ機能です。利用は Windows 95、98、XP で動作するようにしたいのです。
リンク先を読んで見ました。
すると「net time」コマンドで Windows 9x、Me、NT、2000、XP で利用可能と
なっていました。とても便利そうなコマンドですね。
このようなコマンドを自分でも作成(実装)したいです。
実装方法の具体的(ソース)のアドバイスか、実装例が載っているサイトを
ご存知の方、情報をお待ちしています。
あとtetrapodさんにお聞きしたいのですが。
いろいろ検索していたら次のリンクを見つけました。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200603/06030019.txt
そして
http://msdn.microsoft.com/library/ja/default.asp?
url=/library/ja/jpnetmg/html/_win32_NetRemoteTOD.asp
のリンクも見つかりました。おまけに C 言語でのサンプルまで。
このサンプルで得た時刻(pBuf->tod_yearなど)をそのまま SetLocalTime() で
設定すれば時刻修正できるという事でよろしいでしょうか?
もしこれで良いのならもう一つ。
サンプルで pszServerName = argv[1] にセットする文字列は Unicode ですが、
どういう風にすれば良いのでしょうか?
普段は NTP サーバーとして ntp.jst.mfeed.ad.jp を使っています。
指定する文字列は L\\\\ntp.jst.mfeed.ad.jp で良いのですか?
お返事を待っています。
追記。
タイムゾーンはどうなります?
日本は +9 加算すれば良いのですか?
こちらのアドバイスもお願いします。
また追記です。
いろいろと調べたら NetRemoteTOD() API は Windows95、98 では使えないようですね。
Windows95、98 の場合はどうすれば良いでしょうか?
ご存知の方がいましたらアドバイスをお願いします。
TCP/IPの書籍などはNTPプロトコルの実装例は幾つかあるのですけどね…。
仕様そのものはこれあたりを参考にしてはどうでしょうか。
http://www.7key.jp/nw/technology/protocol/sntp.html#format
複数あるようなので、「NTP ルート遅延」あたりで検索して自分に適したものを
探すといいかもしれません。
ソースコードはとりあえずソースコード検索などで検索してみて探してみてはどうで
しょう。
例: http://www.google.com/codesearch?q=NTP+123&hl=ja
最悪Linux用のNTPクライアントを参考にする事でも出来なくは無いかと思いま
すが。
一寸違うかも知れませんが
http://www.nihira.jp/cyber/ntp.html
で言われているTIMEプロトコルのほうが簡単かも知れません。
時間あわせは昔から要望が多い=複数のプロトコルが存在するので話が面倒。
んで有名な3つが Time/NTP/SNTP (SNTP は NTP の簡略版だが)
# プロトコル (protocol) = 外交儀礼、礼儀作法
# コンピュータ世界では (特に通信での) 手続き
たとえば unix 系では遠隔マシンと時刻を合わせる機能が複数あり
ntpdate (SNTP を使う) : 今この瞬間の時刻を合わせる
自分のマシンの時刻が大きく遅れている→時刻をジャンプして進めてしまう
自分のマシンの時刻が大きく進んでいる→時刻をジャンプして逆行させてしまう
自分のマシンの時計の精度が良くない→またすぐに時刻が狂う
xntpd, ntpd (NTP を使う) : 時刻をゆっくり同期させる
自分のマシンの時刻が大きく遅れている→時間を速めに数えることで同期する
自分のマシンの時刻が大きく進んでいる→時間を遅めに数えることで同期する
自分のマシンの時計の精度が良くなくても、常に相手と同期させることができる
XP/Vista のインターネット時刻同期は ntpdate 相当。
時刻が一気にジャンプして戻るのはファイルサーバ等の運用などにおいては
いろいろと問題が多いので、サーバでは (x)ntpd を使うのが普通。
が、徐々にあわせるのは技術的に難しく NTP 自体も難しいプロトコルになってる。
NTP ではトラフィックが微量だが継続的に生じるのでダイアルアップ等には向かない。
などの特徴がある。
net time コマンドはプロトコルとして MS-NETBIOS を使うため S/NTP ではない。
NetRemoteTOD は NETBIOS レベルのようなので NTP に同期するのは無理っぽい。
# 詳細未調査。
で、この先は「具体的に何がしたいのか」で異なるわけだが・・・
NTP なの? SNTP なの? MS-NETBIOS で十分なの?
ntpd 相当のこと=常時同期をするのは多分かなり面倒。
この瞬間だけ同期ならそんなに難しくないと思うよ。
VC++6/SNTP でよければ、拙作の Donut RAPT で実装しているので
そのソースコードが参考になるかもしれません。
麩さん、tetrapodさん、RAPTさん。
いろいろな情報とアドバイスをありがとうございます。
ntpdate コマンドは調べていたら見つかりましたが MacOS となっていました。
Unix 系でもあるのですね。
>で、この先は「具体的に何がしたいのか」で異なるわけだが・・・
>NTP なの? SNTP なの? MS-NETBIOS で十分なの?
>ntpd 相当のこと=常時同期をするのは多分かなり面倒。
>この瞬間だけ同期ならそんなに難しくないと思うよ。
やりたいことは、今の瞬間だけ時刻の同期を取れれば良いと思っています。
なので
>XP/Vista のインターネット時刻同期は ntpdate 相当。
このタイプです。今、この瞬間だけ時刻を合わせる機能です。
>この瞬間だけ同期ならそんなに難しくないと思うよ。
難しくないとの事ですがどうすればよろしいでしょうか?
また NetRemoteTOD() で簡単に出来るのかと思っていましたが
この関数では行えないのでしょうか?
これで今の瞬間だけ時刻をあわせることが出来るのなら楽なのですが…。
NetRemoteTOD() は NETBIOS レベルとなっていますが、この関数の第一引数には
どんな文字列を指定すべきなのでしょうか?
MSDNマニュアルでは
>この関数を実行するリモートサーバーの名前を表す、Unicode 文字列へのポインタ
>を指定します。この文字列の先頭は \\ でなければなりません。このパラメータが
>NULL の場合、ローカルコンピュータを使います。
となっています。リモートサーバー名とは何ですか?
また先頭に \\ を単純に追加すれば良いのですか?
いろいろとアドバイスをお願いします。
RAPTさんへ。
検索したら http://rapt21.com/ が見つかりました。
>そのソースコードが参考になるかもしれません。
ソースを参照できるのなら参考にして見たいですがどこにありますか?
次のページは見つけました。
http://www.atmark.gr.jp/~s2000/r/files/src/#Language_last
このうちのどれになりますかね。
1つダウンロードしてみましたが大量のファイルがあり過ぎで見つけるのが困難です。
ダウンロードする書庫ファイルだけでも教えて欲しいです。
書庫内は自分で探しますがファイル名もあれば助かります。
ちなみに 1~83 の数や日付はバージョンによっての違いなのでしょうか?
いろいろとお願いします。
追記。
ネット関連(TCP/IP)の書籍を買おうと思います。
お勧めの本があれば紹介して下さい。
またネット用語(プロトコル,サーバー,etc)の本かサイトも一緒に
紹介して欲しいです。
こちらの情報もお待ちしています。
現時点での最新ソースは、2007/06/26 Donut RAPT #115 です。
sntp.h 内の class CSntp がその実装です。
RAPT さん。
ありがとうございます。
>sntp.h 内の class CSntp がその実装です。
ソースを覗いてみました。
直ぐには理解できないですがじっくりと解読します。
一通り解決という事でチェックしておきます。
また何かありましたら質問します。