IPアドレスの入手


別のマシンのプロセスと通信するには、まずそのマシンのネットワークに おけるアドレスを知らないと接続先すら指定できません。マシンには例えば "www.yahoo.co.jp" のような分かりやすいホスト名が付いていますが、 プログラムで用いるのはこのホスト名の文字列ではなくて、対応する IPアドレスと呼ばれる4byteの数字です。

注意: 現在は IPアドレスは4byteの数字で 表す IPv4規格がほとんどですが、将来は 16byteの数字で表す IPv6規格に 移行していきます。

IPアドレスにあまり慣れていない読者はプログラムを作る前に kterm 上でいくつかコマンドを実行してIPアドレスに慣れましょう。 まず、自分のマシンのIPアドレスがどうなっているのかは ifconfig コマンドでわかります。

/home/naoki/> ifconfig -a xl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 options=3<rxcsum,txcsum> inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255 ether 00:00:86:42:f2:f2 media: Ethernet autoselect (100baseTX <full-duplex>) status: active lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 inet 127.0.0.1 netmask 0xff000000
このようにこのマシンには2つのネットワーク装置が付いていて、 それぞれが 192.168.1.2 と 127.0.0.1 のIPアドレスを 持っていることがわかります。この 127.0.0.1 の方はループバックアドレスと 呼ばれるソフトウェア的なネットワーク装置で、このIPアドレスへのアクセスは 本物のネットワーク装置を介さないで、そのマシン自身へのアクセスとなります。 なのでネットワークプログラムの練習にはもっぱらこのIPアドレスへのアクセス で行います。他方の 192.168.1.2 がこのマシンの対外的な IPアドレスで 他のマシンはこのIPアドレスでこのマシンを指定するわけです。もちろん 自分自身でこのIPアドレスに接続することもできます。

次に、他のマシンのIPアドレスを調べるには host コマンドを使います。 例えば Yahoo Japan の web server である www.yahoo.co.jp のIPアドレスを 調べてみましょう。

/home/naoki/> host www.yahoo.co.jp www.yahoo.co.jp has address 211.14.13.226 www.yahoo.co.jp has address 210.81.150.166 www.yahoo.co.jp has address 210.81.153.68 www.yahoo.co.jp has address 210.81.153.69 www.yahoo.co.jp has address 210.81.153.70 www.yahoo.co.jp has address 211.14.13.65 www.yahoo.co.jp has address 211.14.13.66 www.yahoo.co.jp has address 211.14.13.222 www.yahoo.co.jp has address 211.14.13.224 www.yahoo.co.jp has address 211.14.13.225
www.yahoo.co.jp にはここに表示されているように複数のIPアドレスが 対応していることがわかります。 www.yahoo.co.jp のような大賑わいな web serverの場合は複数のマシンが 分担していることがよくあります。複数のIPアドレスのうちのどれか1つを ランダムに選択してそのIPアドレスに接続するようにすれば、負荷がうまく 分散できるというわけです。実際、何度か host コマンドでIPアドレスを 調べて見て下さい。IPアドレスのリストは毎回順番が異なります。


さて、プログラムでホスト名からIPアドレスを調べるには gethostbynameという関数を使うのですが、これの使い方がちょっとだけ 込み入ってますので、ここではそれを簡単に使えるように"かぶせもの"を 用意しましたので以後のプログラムでもこれを使うことにします。 初学者の方はこの関数の中身は無視して使い方だけ覚えて下さい。
in_addr InAddr( const char* hostname ) { hostent* hp; in_addr sin_addr = {0}; if( (hp = gethostbyname( hostname )) != NULL ){ sin_addr = *(in_addr*) hp->h_addr; } return sin_addr; }
この関数は私の自作ヘッダーファイル integnet.hに 用意してありますのでこれをダウンロードしてください。

この関数 InAddr() には引数にホスト名の文字列を与えます。この関数は ホストのIPアドレスの数字を in_addr 型と呼ばれる構造体に格納して返します。 この関数は例えば以下のようにして利用します。

// program ip.cc #include <stdio.h> #include <arpa/inet.h> #include "integnet.h" main() { in_addr IP = InAddr("www.yahoo.co.jp"); if( h_errno ){ herror("gethostbyname"); exit(1); } printf("%s\n", inet_ntoa(IP) ); return 0; }
関数 InAddr()がホストのIPアドレスを調べられなかった場合には 広域変数 h_errno の値が 0 以外になっているので、その場合には herror()関数でエラーの原因を表示することができます。
関数 inet_ntoa は in_addr型構造体に格納されているIPアドレスを 文字列に変換する関数で arpa/inet.h にそのプロトタイプが定義されています。


目次

Copyright(C) by Naoki Watanabe. Jan 1st, 2001.
渡辺尚貴 naoki@cms.phys.s.u-tokyo.ac.jp