2021年2月13日土曜日

gethostbyname の動作の理解 hostent構造体のh_addr_listの理解 なぜポインタになっているのか hostentの実体は

 


 name_test_three2.c  yname_test_three.c  ~/d/m/gcc  test.c                       X

//車輪のx発明 ~B.G's Blog~

//https://bg1.hatenablog.com/entry/2015/09/04/210000

//

//上サイトの説明がわからなかったので実験

//**h_addr_listにを使わずに数値を代入

//どうなるか実験

//数値は hostbyname_test_three.c の実行結果2 

//を使用


// よくわからんので適当にincude

#include <stdio.h>

#include <sys/socket.h>  //ソケット

#include <sys/types.h>   //派生型

#include <arpa/inet.h>   //IPアドドレス変換

#include <netdb.h>       //ホスト名変換


typedef struct hostent_my

{

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

  char **h_aliases;//エイリアス(別名)リスト。(NULLで終わる配列)

  int  h_addrtype; //アドレスタイプ(AF_INETとか)

  int  h_length;   //アドレスの長さ

  char **h_addr_list;//IPアドレスのリスト

                     //ネットワークアドレスの情報へのポインタの配列

} hostent_my2;



int main(void){

    //host = gethostbyname(hostname);とすると、hostent構造体のポインタと

    //実体が同時にでき、ポインタに実体のアドレスが代入されるようだ。

    //ここではそれを手動でする

    hostent_my2 host_zittai, *host_my;

    host_my = &host_zittai;


    //struct hostent *host;

    char *host_str;     //ホスト名文字列

    struct in_addr addr;


    //hostbyname_test_three.c  実行結果2のデータをいれる

    char a1 = (char)0xd8;

    //printf("数値から文字列への変換 %c\n", a1);

    char a2 = (char)0x3a;

    //printf("数値から文字列への変換 %c\n", a2);

    char a3 = (char)0xc5;

    //printf("数値から文字列への変換 %c\n", a3);

    char a4 = (char)0x03;

    //printf("数値から文字列への変換 %c\n", a4);



    // pointer_pointer3.c 参考

    //**h_addr_listはポインタ配列という話をどこかできいたので,,,

    // **h_addr_listはポインタの配列らしいので以下のように考えてみる

    //

    //h_addr_list[0][0] で ap[0][0] にアクセスできる

    //

    char a11[4] = {a1, a2, a3, a4};

    char *ap[5];  //ポインタの配列

    ap[0] = a11;  //ポインタの配列の要素0にa11を代入

    host_my->h_addr_list = ap;



    // このコードとは関係がないが、参考のため以下をメモる

    //https://www.geekpage.jp/programming/winsock/tips-gethostbyname.php

    //struct hostent *の実体は最後にgethostbynameが利用された時の値に毎回

    //書き換えられてしまいます。


    // // hostentの実体をgethostbynameを使って作成。

    // // ダミーにヤフーホスト名を入れる

    // host = gethostbyname("www.yahoo.co.jp");

    // if (host==NULL){

    //  printf("error gethostbyname \n");

    //  return -1;


    //printf 1 実行

    // gethostbyname_test_three.cのgethostbynameを使っての実行結果と同じ

    printf("host_my->h_addr_list[0][0] = %02x\n\

host_my->h_addr_list[0][1] = %02x\n\

host_my->h_addr_list[0][2] = %02x\n\

host_my->h_addr_list[0][3] = %02x\n\n",\

host_my->h_addr_list[0][0],\

host_my->h_addr_list[0][1],\

host_my->h_addr_list[0][2],\

host_my->h_addr_list[0][3]);


    printf("\n");


    //addr(in_addr_t).s_addr はuint32_t(32ビットの符号なし整数型)

    //なので addr.s_addrにポインタを渡してみる

    addr.s_addr = *(in_addr_t *)host_my->h_addr_list[0];


    // gethostbyname_test_three.cのgethostbynameを使っての実行結果と同じ

    //h_addr_list[0]を16進数として出力を addr.s_addrに代入

    printf("add.s_addr = %x\n\n", addr.s_addr);


    host_str = inet_ntoa(addr);

    printf("host_str = %s\n", host_str);

    return 0;

}


/*

実行結果

host_my->h_addr_list[0][1] = 3a

host_my->h_addr_list[0][2] = ffffffc5

host_my->h_addr_list[0][3] = 03


add.s_addr = 3c53ad8

host_str = 216.58.197.3


*/

~                                                                                 

~                                                                                 

~                                                        

0 件のコメント:

コメントを投稿

About

参加ユーザー

連絡フォーム

名前

メール *

メッセージ *

ページ

Featured Posts