gethostbynameという関数の使用方法について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
わたる
記事: 4
登録日時: 5年前

gethostbynameという関数の使用方法について

#1

投稿記事 by わたる » 5年前

現在パケットプログラミングについて勉強中なんですが、色々分からないことが出てきています。

題名の通り、gethostbynameという関数の使い方が分かりません。

また、gethostbynameの出力値は構造体へのポインターなのですが、それが

hostentという構造体になり、この中身についても良く分かりません。

理解に力を貸してくださる方、返答お願いします。


わたる
記事: 4
登録日時: 5年前

Re: gethostbynameという関数の使用方法について

#3

投稿記事 by わたる » 5年前

早速の回答ありがとうございます。

hostentという構造体について一体どのようなものなのかが分からないのですが、質問の内容が曖昧ですいません。
例えば以下のように、yahoo.co.jpのIPアドレスを取得したい場合には、
hostentという構造体の中は最初空の状態で、yahoo.co.jpというホストアドレスが持っている情報が、
hostentという構造体へ格納されるということでよろしいのでしょうか?

コード:

#include<stdio.h>
#include<netdb.h>
int main(void){
  struct hostent *hostent;
  hostent = gethostbyname(yahoo.co.jp);
・・・以下略
構造体hostentの中身は以下のようになっていますが、
「h_addrtype」というのはyahoo.co.jpのIPアドレスがIPv4なのか、IPv6なのかとか、どういう形式であるかを自動的に取得して
h_addrtypeへ格納してくれるということよろしいのでしょうか?指定と書いてあるので、最初から指定されているものなのでしょうか?
ご教授願います。

コード:

struct hostent{                                                             
   char FAR* h_name;      ホストの正式名称(FDQN)                    
   char FAR FAR** h_aliases;  ホストの別名が格納される、NULLで終わる配列へのポインター                                                           
   short h_addrtype;      アドレスタイプ(通常はAF_INET(2))を指定    
   short h_length;       アドレスのサイズ(IPv4の場合は4,IPv6の場合は16を指定)                                            
   char FAR FAR** h_addr_list; アドレスのリストが格納される、NULLで終わる配列へのポインター

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: gethostbynameという関数の使用方法について

#4

投稿記事 by h2so5 » 5年前

わたる さんが書きました: hostentという構造体の中は最初空の状態で、yahoo.co.jpというホストアドレスが持っている情報が、
hostentという構造体へ格納されるということでよろしいのでしょうか?
struct hostent *hostent; は構造体のポインタであって構造体そのものではありません。
gethostbynameはhostent構造体のポインタを返します。
わたる さんが書きました: 構造体hostentの中身は以下のようになっていますが、
「h_addrtype」というのはyahoo.co.jpのIPアドレスがIPv4なのか、IPv6なのかとか、どういう形式であるかを自動的に取得して
h_addrtypeへ格納してくれるということよろしいのでしょうか?指定と書いてあるので、最初から指定されているものなのでしょうか?
それは実行してみれば分かる話だと思いますが。

zeek

Re: gethostbynameという関数の使用方法について

#5

投稿記事 by zeek » 5年前

質問に対する直接の回答ではなく参考情報です。
名前解決には gethostbyname() より getaddrinfo() が RFC 2553 以降 (現在は RFC 3493) で推奨されていたと思います。
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
に getaddrinfo() の sample code があります。

わたる
記事: 4
登録日時: 5年前

Re: gethostbynameという関数の使用方法について

#6

投稿記事 by わたる » 5年前

構造体の中にFARという謎の文字が含まれており参照ができないです。
参照の仕方がわかれば確認できるのですが。。。

ちなみにLinuxでプログラミングをしています。

以下の方法では通りませんでした。

コード:

#include<stdio.h>
#include<netdb.h>

int main(void){

  struct hostent *hostent;

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

  //ここで、hostentの中身について。                                                                                       
  //hostentとは*hostentという構造体の実態を指すポインター。                                                                     
  //                                                                                                                                  
  //struct hostent{                                                                                                                   
  //   char   FAR*     h_name;       ホストの正式名称(FDQN)                                                                     
  //   char   FAR FAR**  h_aliases;   ホストの別名が格納される、NULLで終わる配列へのポインター                                     
  //   short        h_addrtype;  アドレスタイプ(通常はAF_INET(2))を指定                                                     
  //   short        h_length;     アドレスのサイズ(IPv4の場合は4,IPv6の場合は16を指定)                                
  //   char   FAR FAR**  h_addr_list; アドレスのリストが格納される、NULLで終わる配列へのポインタ                                   
  //};                                                                                                                                
  // hostentというポインター型変数が指す先の実態 → *hostent                                                                        
  // その中のchar型のh_nameを指定するには、(*hostent).h_name                                                                          
  // hostent->h_nameと同じ                                                                                                            

  pirntf("hostname:%s\naddrtype:%d\nlength:%d\n",hostent->h_name,hostent->h_addrtype,hostent->h_length);

  return 0;
}

アバター
へにっくす
記事: 630
登録日時: 8年前
住所: 東京都

Re: gethostbynameという関数の使用方法について

#7

投稿記事 by へにっくす » 5年前

linuxならこちらを参照してください。
Geekなぺーじ:Linuxネットワークプログラミング
上記のページに、いくつかのサンプルページがリンクされています。
written by へにっくす

アバター
みけCAT
記事: 6297
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: gethostbynameという関数の使用方法について

#8

投稿記事 by みけCAT » 5年前

  • C言語の標準関数にpirntfは無さそうです。printfにしてみてください。
  • ホストが見つからず、NULLが返っているかもしれません。
    "//www.yahoo.co.jp"を"www.yahoo.co.jp"や"192.168.1.1"にして試してみてください。
    8行目の直後に

    コード:

    printf("%p\n",(void*)hostent);fflush(stdout);
    という行を加えると、NULLが返っているか確認できるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

わたる
記事: 4
登録日時: 5年前

Re: gethostbynameという関数の使用方法について

#9

投稿記事 by わたる » 5年前

以下のコードであと少しなのですが、IPアドレスの表示がうまくできません。。。
教えていただけると助かります。

コード:

#include<stdio.h>
#include<netdb.h>

int main(void){
  int i;
  struct hostent *hostent;

  hostent = gethostbyname("www.yahoo.com");
  printf("%p\n",(void*)hostent);fflush(stdout);                                                                                                                   
  printf("h_name:%s\n",hostent->h_name);                                                                                       

  printf("h_aliases[0]:%s\n",hostent->h_aliases[0]);
  printf("h_aliases[1]:%s\n",hostent->h_aliases[1]);

  printf("h_addrtype:%d\n",hostent->h_addrtype);                                                                                   
  printf("h_length:%d\n",hostent->h_length);                                                                                     
  printf("h_addr_list[0](ポインタ型):%p\n",hostent->h_addr_list[0]);
  printf("h_addr_list[1](ポインタ型):%p\n",hostent->h_addr_list[1]);
  printf("\n");printf("\n");

  printf("h_addr_list[0](ストリング型):%d\n",hostent->h_addr_list[0]);
  printf("h_addr_list[0]+1(ストリング型):%s\n",(hostent->h_addr_list[0])+1);
  printf("h_addr_list[0]+2(ストリング型):%s\n",(hostent->h_addr_list[0])+2);
  printf("h_addr_list[0]+3(ストリング型):%s\n",(hostent->h_addr_list[0])+3);
  printf("\n");

  printf("h_addr_list[1]:%s\n",hostent->h_addr_list[1]);

  //ここで、hostentの中身について記述しておく。                                                                                       
  //hostentとは*hostentという構造体の実態を指すポインターである。                                                                     
  //                                                                                                                                  
  //struct hostent{                                                                                                                   
  //   char   FAR*     h_name;       ホストの正式名称(FDQN)                                                                     
  //   char   FAR FAR**  h_aliases;   ホストの別名が格納される、NULLで終わる配列へのポインター                                     
  //   short        h_addrtype;  アドレスタイプ(通常はAF_INET(2))を指定       
  //   short        h_length;     アドレスのサイズ(IPv4の場合は4,IPv6の場合は16を指定)                                             
  //   char   FAR FAR**  h_addr_list; アドレスのリストが格納される、NULLで終わる配列へのポインタ                                   
  //};                                                                                                                                
  // hostentというポインター型変数が指す先の実態 → *hostent                                                                        
  // その中のchar型のh_nameを指定するには、(*hostent).h_name                                                                          
  // hostent->h_nameと同じ                                                                                                            

  return 0;
}
結果は以下のようになりました。

コード:

0xb771a9a0
h_name:fd-fp3.wg1.b.yahoo.com
h_aliases[0]:www.yahoo.com
h_aliases[1]:(null)
h_addrtype:2
h_length:4
h_addr_list[0](ポインタ型):0x8a40130
h_addr_list[1](ポインタ型):(nil)


h_addr_list[0](ストリング型):j
�
h_addr_list[0]+1(ストリング型):
�
h_addr_list[0]+2(ストリング型):�
h_addr_list[0]+3(ストリング型):
h_addr_list[0]+4(ストリング型):

アバター
へにっくす
記事: 630
登録日時: 8年前
住所: 東京都

Re: gethostbynameという関数の使用方法について

#10

投稿記事 by へにっくす » 5年前

No.9のコードと結果が違ってますね。
結果の最後の行にあたる部分がコードに見受けられません。
h_addr_list[0]+4ってどこさ?
また、h_addr_listの表示の仕方が間違っています。
No.2でh2so5さんがはってくれているリンク先の、サンプルコードをよく読むことをオススメします。
written by へにっくす

閉鎖

“C言語何でも質問掲示板” へ戻る