サーバーが稼働中かどうかを調べる方法

戻る

インターネット上には,いろいろなサーバーが稼動していますが,自分がアクセスを 行うサーバーが起動中かどうかを調べるには,サーバーにアクセスするしか ありません.しかし,WebサーバーにアクセスするためにHTTPでアクセスをすると, もしサーバーが起動していなかったときには処理がタイムアウトするまで,待つことに なります.また,自分の送信したデータがサーバーに伝わっているかを調べる必要が あるとき,HTTPやFTPを利用するには,相手側にそれらのサーバーが起動されている 必要があります.そこで,もっと簡単に Windows95/98,NT,UNIXマシンに特別な デーモンやサービスが起動されていなくても,相手のマシンが起動中であるかを確認 する方法を考えてみましょう.

3-1 PING.EXE

PING.EXE は, Windows95/98/NT に TCP/IP をインストールするとドライバーと共に インストールされます."PING"は,Packet InterNet Groper の略で, 「インターネット上のマシン探索装置」を意味しています.このコマンドは元々UNIXの コマンドですが,TCP/IPのネットワーク上で PING.EXE を利用すると,相手のマシンが 起動中であるか,ネットワークが問題なく接続されているかを知ることができる便利な コマンドです.

3-2 PINGの仕組み

PINGコマンドは特別なプロトコルを利用して相手に送信し,その応答を受信することで 起動中であるかを判断します.もし,応答が戻ってこなければ,相手のマシンが動作 していないか,ネットワークにトラブルがあるかもしれません.この場合少なくとも, HTTPやFTPでアクセスしても,接続することができない状態であるため,無駄な通信で タイムアウトまで待つといったことを避けることができます.

コラム●PINGはICMPで通信する

PINGは,TCP/IP の TP と同じ層に定義されている ICMP(Internet Control Message Protocol)を利用します.このプロトコルは,ICMPメッセージのデータグラムを送信 し,その応答を受信することで,相手が存在することを確認します. しかし,このパケットはネットワーク上のどこかで紛失することもありますので, 数回発信を行って返信があるかを確認しなければなりません.
また,同じマシン内に複数のPINGアプリケーションがいると,他のアプリケーションが 発信したパケットも受信してしまいます.このため,自分が発信したメッセージに 印をつけておいて,自分が発信したメッセージへの返信であることを確認する必要が あります.

図3-A:OSIの階層.ICMPはIPと同じ層に定義されている
+------------------------------+ +-----------------------------+ OSI 4層 | T C P | | U D P | +------------------------------+ +-----------------------------+ +---------------+ +--------------+ +-------------+ +-----------+ OSI 3層 | I C M P | | I P | | A R P | | R A R P | +---------------+ +--------------+ +-------------+ +-----------+ +--------------------------------------------------------------+ OSI 1,2層 | ハードウェア | +--------------------------------------------------------------+

3-3 ICMP.DLLを使う

ICMP.DLLは,PING を行うための処理を持っています.このDLLに含まれるAPIは, 正式に公開されておらず,今後削除されるかもしれないということです. しかし,WindowsCE2.0では正式にWin32 APIとして公開されています. これらのAPIを利用するには,WinSock API WSAStartup を呼び出す必要があります. IcmpSendEcho を呼び出すと,応答を受信するか指定されたタイムアウト時間を超える まで,処理を戻しません.
このAPIを使うと ICMP についての知識も要りませんし,簡単な手順で PING の処理を 自分のアプリケーションに組み込むことができます.

表3-1:ICMPエコーAPI.今後削除される可能性がある
HANDLE IcmpCreateFile(VOID)
Icmpファイルハンドルを開く

引数
HANDLE hIcmp ... ICMPハンドル

戻り値
正常終了 ICMPハンドル
異常終了 INVALID_HANDLE_VALUE
DWORD IcmpSendEcho(HANDLE hIcmp, IPAddr DestinationAddress,
 LPVOID lpvRequestData, WORD wRequestSize,
 PIP_OPTION_INFORMATION RequestOptions,
 LPVOID lpvReplyBuffer, DWORD dwReplySize,
 DWORD dwTimeout)
Icmpエコーを送信する

引数
HANDLE hIcmp ... ICMPハンドル
IPAddr DestinationAddress ... 送信先IPアドレス
LPVOID lpvRequestData ... リクエストデータバッファ
WORD wRequestSize ... リクエストデータサイズ
PIP_OPTION_INFORMATION RequestOptions ... IPヘッダオプション
LPVOID lpvReplyBuffer ... リプライバッファ
DWORD dwReplySize ... リプライバッファサイズ
DWORD dwTimeout ... タイムアウト時間[msec]

戻り値
リプライを受けたパケット数
BOOL IcmpCloseHandle(HANDLE hIcmp)
Icmpファイルハンドルを閉じる

引数
HANDLE hIcmp ... ICMPハンドル

戻り値
TRUE 正常終了
FALSE 異常終了

3-4 WinSockAPIを使う

特別なAPIを利用しなくても,ソケットAPIを利用すればICMP の送信を行うことが できます.この場合,ICMPヘッダーに自力で値を設定して返信されたパケットの 値も自分で参照する必要があります.UNIXの場合,IPヘッダーやICMPヘッダーの構造体 は,インクルードファイルに含まれますが,Win32 SDKやVC++にはそのような情報は ありませんので,自分で構造体を定義しなければなりません.
PING の処理は,ICMPメッセージのうち ICMP_ECHO(エコー要求)とICMP_ECHOREPLY (エコー返信)を利用します.それ以外のメッセージについては,RFC 792 を参照して ください.ここでは、IPv4,ICMPv4を利用していますが、64ビットIPアドレスに対応 したIPv6, ICMPv6 が発表されています.

●手順
PING の処理は次のような手順で行います.
1) WinSock API の初期化
2) 送信先のIPアドレスの取得
3) ソケットをオープンと,タイムアウト時間の設定
4) ICMPヘッダに値を設定
5) sendto でICMPパケットを送信
6) recvfrom で返信を受け取る
7) 受信したパケットが自分が送信したものに対するものであるかをチェックする
送信したパケットは,ネットワーク上で紛失する可能性がありますので, 確実に相手が存在するかを確認するには 5), 6)を数回繰り返したほうがよいでしょう. また,自分の送信したものでないICMPパケットの返信を受け取ることがありますので, 7)では自分の発信したパケットへの返信であるかの判定も行う必要があります.
ICMPパケットにオプションデータとして,アプリケーション固有情報を埋め込むことが できますので,それを利用して返信までの所要時間の取得やパケットのチェックを行う ことができます.

●ICMPが返信されるまでの時間の使い道
ICMP Echoメッセージの返信が返ってくる時間を計測すると,ネットワークの負荷を ある程度測定することができますので,アプリケーションで安易な負荷診断に利用 できるのではないかと思います.ただし,ネットワークの経路まで考慮する必要がある 場合は,他のメッセージを利用する必要があります.

表3-2:ICMPメッセージタイプ
タイプ内容
0Echo Reply
3Destination Unreachable
4Source Quench
5Redirect
8Echo
9Router Advertisement
10Router Selection
11Time Exceeded
12Parameter Probrem
13Timestamp
14Timestamp Reply
15Infomation Request
16Information Reply
17Address Mask Request
18Address Mask Reply
30Traceroute
37Domain Name Request
38Domain Name Reply


図3-1:IPv4ヘッダ (RFC 791) 0 4 8 16 20 24 31 [bit] +-------+-------+---------------+-------------------------------+ |バージョン| ヘッダ長|サービスタイプ | トータル長 | +-------+-------+---------------+-------+-----------------------+ | 識別子 | フラグ| フラグメントオフセット| +---------------+---------------+-------+-----------------------+ | 生存時間 | プロトコル | ヘッダーチェックサム | +---------------+---------------+-------------------------------+ | 送信元IPアドレス | +---------------------------------------------------------------+ | 送信先IPアドレス | +---------------------------------------------------------------+ | オプション(可変長) | +---------------------------------------------------------------+ 図3-2:ICMPv4ヘッダ (RFC 792) 0 8 16 31 [bit] +---------------+---------------+-------------------------------+ | タイプ | コード | チェックサム | +---------------+---------------+-------------------------------+ 図3-3:sendto で送信する情報 +--------------+--------------------+ | ICMPヘッダ | ICMPオプション | +--------------+--------------------+ 図3-4:recvfrom で受信する情報 +---------------------+--------------+--------------------+ | IPヘッダ | ICMPヘッダ | ICMPオプション | +---------------------+--------------+--------------------+


3-5 Macは応答しなかった

Apple社のPC(Performa 6260)にネットワークカードを増設し,接続できたかを確認 するために,他のマシン(Windows95)からPING を利用しましたが,応答がありません でした.どうやら,MAC TCP/IP には ICMP エコーに応答する機能がないようです. 現在のMAC OS ではどうなっているかは分かりませんが,簡単に通信が可能であるかを 確認する方法がなかったので動作を確認するまで手間取ってしまいました.
このように,OSによってはICMPエコーに応答する機能を持たない場合があります. ICMPをマシンが起動されているかをチェックするアプリケーションを作成するとき には,ターゲットマシンで可能であるかをあらかじめチェックしておいたほうがよい でしょう.

3-6 プログラムについて

ICMPのECHOパケットを送受信するサンプルです. プログラムは,IcmpSendEcho を利用するものと,WinSockで行うものがあります. 両方とも1度の送信と受信を行い,結果を表示します.
IcmpSendEchoを利用してコンパイルするには,Win32 SDK の ICMPAPI.H, IPEXPORT.H, ICMP.LIB を利用する必要があります.ICMP.DLLは,標準でインストールされる モジュールのようですが,再配布可能モジュールではありませんし,IcmpSendEcho は Win32 API として認知されていないようです.実際に利用するときは,ターゲット システムに標準でインストールされているかを確認してから利用したほうがよいで しょう.
MAKEFILE に WIN32.MAK を利用していますが,Visual C++ ver6.0 で,WSOCK32.DLLを 利用するには,
TARGETOS = WIN95
APPVER = 4.0
を指定する必要があります.
それ以外の指定をすると,WS2_32.DLL がリンクされ,Windows95 では実行できなく なってしまいます. なお,ソケットAPI のエラーメッセージをWin32 API FormatMessage で取得しています が,Windows98では取得できません.

●ソースファイル
ICMP\PING.EXE(IcmpSendEcho版Ping)
PING.C(ソースファイル)
MAKEFILE(メイクファイル)
WINSOCK\PING.EXE(WinSock版Ping)
PING.C(ソースファイル)
PING.H(ヘッダファイル)
MAKEFILE(メイクファイル)