< Enum と RadioButton をバインドする | メモ: ListBox や ListView の行番号 >

October 10, 2008

メモ:自身の IP アドレスを取得する方法

Winsock での方法は、Winsock Programmer's FAQ: Winsock 中級者向けの議論 にありあり。

3.3 - Winsock プログラム で自分の IP アドレスを取得する方法は?

3種類の方法があり、それぞれに利点、欠点があります:

  1. 最も簡単な方法は、connect 済みのソケットに対して getsockname() を呼び出すことです。connect 済みのソケットが無ければ、その呼出しは失敗するか、あるいは無意味な情報が返されます。
  2. ソケットを事前にオープンすることなしに自分のアドレスを取得するには、gethostname() の返却値に対して gethostbyname() を呼び出すことです。この例に示すように、この呼出しはそのホストが持つ全てのインターフェースのリストを返却します。 (この方式の問題点については、例のページを参照のこと。)
  3. 三番目の方法は Winsock 2 でのみ動作します。新しい WSAIoctl() API は SIO_GET_INTERFACE_LIST オプションをサポートしており、返却される情報の一部として、システムの各々のネットワークインターフェースのアドレスが返却されます。[C++ の例] (これも、注意点については例のページを参照のこと。)

後者二つの方式では、多くの TCP/IP ネットワークのマシンでは少なくとも二つのアドレスが返却されます。一つは「普通の」ネットワークインターフェースで、一つは「ループバック」ネットワークインターフェースになるはずです。通常、「普通の」ネットワークインターフェースはモデムかイーサネットカードです。ループバックインターフェース (IPアドレス 127.0.0.1)は、同一のマシン上で動作する二つのプログラムが、オペレーティングシステムのネットワークハードウェアレイヤを通過することなしに通信できるようにさせるものです。ループバックインターフェースを使用した通信は少なくとも普通のネットワークインターフェースと同じ程度の速度であり、ネットワークスタックによってははるかに高速になります。

一つのシステム上に二つ以上のネットワークインターフェースを持つこともあり得ます。多くのサーバでは、例えば二つ以上のネットワークインターフェースカードを持っていると、上記2番目、3番目の方法では4つ以上のエントリーが表示されます。さらに複雑な例はサテライト型インターネットルータで、これにはインターネットへの上流接続を行うモデムコネクション、インターネットからの下流接続を行うサテライトアダプタ、その他の LAN を通信するイーサネットカード、そしてもちろんループバックインターフェースが繋がっています。

もし同じマシン上で動作しているサーバとソケットを使って通信したいのであれば、ループバックインターフェースを使ってください。そうでなければ、普通のインターフェースのうちの一つを、頭をフル回転させて選ばなくてはなりません。全ての目的で使える決まりきった方法はありません。ほとんどのプログラムにおいては、実際にコネクションが使っている IP アドレスが返却されるので、上記の1の方法で十分です。もしこれが使えないのであれば、インターフェースにリストを表示して、ユーザに一つを選ばせる必要があるかもしれません。

PPPインターフェースのアドレスを知りたい、というときのように、より詳細な条件がある場合があります。この場合には上記の 3 の方式が使えます。これによって得られる情報の中には、PPP インターフェースのフラグが含まれるので、これで「ポイントto ポイント」インターフェースかどうかを知ることができるのです。

でも、私が今知りたいのは、C#、つまり .NET Framework を使った方法…。

---------
2008.10.28 追記
System.Net.NetworkInformation.IPInterfaceProperties.UnicastAddresses が、Iphlpapi.dll の GetAdaptersAddresses 関数で取得できるものと同等かも。

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/2207

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?