next up previous contents
Next: ストリーム型ソケット通信 Up: ネットワークプログラムを書く Previous: プログラミングに必要な概念

ネットワークアドレス

相手計算機の指定はネットワークアドレスを用いてやることになるわけです が、通常はアルファベットのホスト名を使っています。システムコールで使え るアドレスに変換するためには2段階の手続きが必要です。まずはじめにホス ト名からIPアドレスに変換します。これにはDNS(Domain Name Service)や NIS(Network Information Service)のデータベースもしくは/etc/hostsが参照 されます。一般的には得られたアドレスは計算機固有の表現で与えられていま す。それをネットワークに送り出すため、ネットワークでの標準的な表現にも う一度変換する必要があります。ネットワークバイトオーダーと呼ばれている 表現は、例えばSUNとDECで32ビットワードの中でのバイトの配置の仕方が違い ます。アドレスの低いほうがワードのLSBに近いビッグエンディアン(VAXや Intel)とMSBに近いリトルエンディアン(SUNやMotorola)の違いです。ネットワー クバイトオーダはリトルエンディアンです。ホストでの表現をネットワーク表 現に変換するhtonsやhtonlとその逆の変換をするntoh sやntohlという関数も しくはマクロが用意されています。

ホスト名をアドレスに変換する関数はgethostbynameです。次の例を見てく ださい。

        #include        <netdb.h>



        struct  hostent *hp;



        hp = gethostbyname( "yaoya" );

        if( hp )        {       /* 変換に成功 */        }

        else    {       /* 変換に失敗 */        }

ホスト名yaoyaの計算機のアドレスを取得します。結果はhostent構造体へのポ インターとして返されます。hostent構造体は次のようなメンバーを持ってい ます。

struct  hostent {

        char    *h_name;                /* ホストの正式名 */

        char    **h_aliases;    /* 別名のリスト */

        int     h_addrtype;     /* アドレスの型。今は無視 */

        int     h_length;               /* アドレス長。4(バイト) */

        char    **h_addr_list;  /* アドレスのリストへのポインタ */

};

実用的に言えばh_addr_listのさす最初の4バイトにアドレスが返ります。

ホスト名を自分のシステムが知らず、130.87.34.1のようにピリオドでオク テットを区切って表わすインターネットアドレスを直接使いたい場合もありま す。これはgethostbynam eは変換してくれません。替わりにinet_addrを使い ます。

        #include        <sys/types.h>

        #include        <sys/socket.h>

        #include        <netinet/in.h>

        #include        <arpa/inet.h>



        unsigned long   uaddr;



        uaddr = inet_addr( "130.87.34.1" );

        if( uaddr == -1 )       {       /* 変換失敗 */  }

        else            {       /* 変換成功 */  }

この場合はunsigned longにアドレスが返ります。

実際のソケット通信ではこのunsigned longのアドレスが必要になります。 上に述べた二つの方法でアドレスを求める手順は次のようになります。

        struct hostent  * hp;

        unsigned long   uaddr;

        char    * hostname;     /* 別のところで設定されている */



        hp = gethostbyname( hostname );

        if( hp )        /* 変換に成功した */

            uaddr = * ( unsigned long * ) ( * hp -> h_addr_list );

        else    /* gethostbynameに失敗した */

        {

            /* "130.87....."かもしれない */

            uaddr = inet_addr( hostname );

            if( uaddr == -1 ) return -1;        /* だめだった。*/

        }

最終的にuaddrにアドレスが入っています。

逆にgethostbyaddr関数を使えば番号で表わされたアドレスのホスト名を調 べることができます。

        hp = gethostbyaddr( ( char * ) &uaddr, 4, AF_INET );

        if( hp )        /* ホスト名はhp -> h_name */

            printf( "Host name is %s\n", hp -> h_name );

これはサーバ側でどのクライアントから接続されたかを知るときに必要です。 相手のアドレスはソケットアドレス構造体にunsigned longの値として返され るからです。



next up previous contents
Next: ストリーム型ソケット通信 Up: ネットワークプログラムを書く Previous: プログラミングに必要な概念



Kinya Hibino
Sun Jan 14 21:36:40 JST 1996