別のマシンのプロセスと通信するには、まずそのマシンのネットワークに おけるアドレスを知らないと接続先すら指定できません。マシンには例えば "www.yahoo.co.jp" のような分かりやすいホスト名が付いていますが、 プログラムで用いるのはこのホスト名の文字列ではなくて、対応する IPアドレスと呼ばれる4byteの数字です。
注意: 現在は IPアドレスは4byteの数字で 表す IPv4規格がほとんどですが、将来は 16byteの数字で表す IPv6規格に 移行していきます。
IPアドレスにあまり慣れていない読者はプログラムを作る前に kterm 上でいくつかコマンドを実行してIPアドレスに慣れましょう。 まず、自分のマシンのIPアドレスがどうなっているのかは ifconfig コマンドでわかります。
このようにこのマシンには2つのネットワーク装置が付いていて、 それぞれが 192.168.1.2 と 127.0.0.1 のIPアドレスを 持っていることがわかります。この 127.0.0.1 の方はループバックアドレスと 呼ばれるソフトウェア的なネットワーク装置で、このIPアドレスへのアクセスは 本物のネットワーク装置を介さないで、そのマシン自身へのアクセスとなります。 なのでネットワークプログラムの練習にはもっぱらこのIPアドレスへのアクセス で行います。他方の 192.168.1.2 がこのマシンの対外的な IPアドレスで 他のマシンはこのIPアドレスでこのマシンを指定するわけです。もちろん 自分自身でこのIPアドレスに接続することもできます。/home/naoki/> ifconfig -a xl0: flags=8843 mtu 1500 options=3 inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255 ether 00:00:86:42:f2:f2 media: Ethernet autoselect (100baseTX ) status: active lo0: flags=8049 mtu 16384 inet 127.0.0.1 netmask 0xff000000
次に、他のマシンのIPアドレスを調べるには host コマンドを使います。 例えば Yahoo Japan の web server である www.yahoo.co.jp のIPアドレスを 調べてみましょう。
www.yahoo.co.jp にはここに表示されているように複数のIPアドレスが 対応していることがわかります。 www.yahoo.co.jp のような大賑わいな web serverの場合は複数のマシンが 分担していることがよくあります。複数のIPアドレスのうちのどれか1つを ランダムに選択してそのIPアドレスに接続するようにすれば、負荷がうまく 分散できるというわけです。実際、何度か host コマンドでIPアドレスを 調べて見て下さい。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
この関数は私の自作ヘッダーファイル integnet.hに 用意してありますのでこれをダウンロードしてください。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; }
この関数 InAddr() には引数にホスト名の文字列を与えます。この関数は ホストのIPアドレスの数字を in_addr 型と呼ばれる構造体に格納して返します。 この関数は例えば以下のようにして利用します。
関数 InAddr()がホストのIPアドレスを調べられなかった場合には 広域変数 h_errno の値が 0 以外になっているので、その場合には herror()関数でエラーの原因を表示することができます。// program ip.cc #include #include #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; }