WinSock gethostbyname

gethostbynameは、ホスト名から、ホスト情報(struct hostent構造体)を取得する。

gethostbynameは、以下のように定義されている。

struct hostent* FAR gethostbyname(
  __in  const char *name          //ホスト名
);

gethostbyname関数が失敗したときには、NULLポインタが返されるが、WSAGetLastError関数で関数が失敗した原因を調べることができる。
gethostbyname関数が失敗したときのWSAGetLastError関数の値は以下の通り。

戻り値説明
WSANOTINITIALISEDこの関数を使う前にWSAStartupの呼び出しを成功させておかなければならない
WSAENETDOWNネットワークサブシステムが停止している
WSAHOST_NOT_FOUND正式なホスト名が見つかりません
WSATRY_AGAIN正式でないホストが見つからない。または、サーバーが停止している
WSANO_RECOVERY回復不能なエラーが発生しました
WSANO_DATA要求されたホスト名は有効である、しかし要求された種類のデータは見つかりませんでした
WSAEINPROGRESSブロッキングWinSock1.1の呼び出しが現在進行中、またはサービスプロバイダーはまだコールバック関数を処理中です。
WSAEFAULTname引数は、有効なユーザーアドレス空間の一部ではない
WSAEINTRブロッキングWinSock1.1の呼び出しは、WSACancelBlockingCallによってキャンセルされた。



戻り値の型であるstruct hostent構造体は以下のように定義されている

struct  hostent {
        char    FAR * h_name;           /* official name of host */
        char    FAR * FAR * h_aliases;  /* alias list */
        short   h_addrtype;             /* host address type */
        short   h_length;               /* length of address */
        char    FAR * FAR * h_addr_list; /* list of addresses */
#define h_addr  h_addr_list[0]          /* address, for backward compat */
};




  • gethostbynameの使用例

  • ウィキペディアドメイン名を名前解決している。

    #include "stdafx.h"
    #include <stdio.h>
    #include <winsock.h>
    
    #pragma comment(lib, "wsock32.lib")
    
    void PrintHostent(LPHOSTENT lpHostEntry)
    {
        printf("HostName: %s\n", lpHostEntry->h_name);
        printf("h_length: %d\n", lpHostEntry->h_length);
        printf("h_addrtype: %s\n", 
            lpHostEntry->h_addrtype == AF_INET ? "AF_INET" : "Unknown address type");
    
        for (int i = 0; lpHostEntry->h_aliases[i] != NULL; i++) {
            printf("h_aliases[%d]: %s\n", i, lpHostEntry->h_aliases[i]);
        }
    
        for (int i = 0; lpHostEntry->h_addr_list[i] != NULL;i++) {
            LPIN_ADDR addr = (LPIN_ADDR)lpHostEntry->h_addr_list[i];
            printf("h_addr_list[%d]: %s\n", i, inet_ntoa(*addr));
        }
    }
    
    int main()
    {
        WSADATA wsaData;
        int nRet;
        LPHOSTENT lpHostEntry;
        DWORD dwError;
        char *lpHostName = "ja.wikipedia.org";
    
        nRet = WSAStartup(MAKEWORD(1, 1), &wsaData);
        if (nRet != 0) {
            fprintf(stderr, "WSAStartup error: %d\n", WSAGetLastError());
            goto EXIT_FUNC;
        }
    
        lpHostEntry = gethostbyname(lpHostName);
        if (lpHostEntry != NULL) {
            PrintHostent(lpHostEntry);
        } else {
            dwError = WSAGetLastError();
            fprintf(stderr, "gethostbyname() error, %d\n", dwError);
            switch (dwError) {
            case WSANOTINITIALISED:
                puts("WSANOTINITIALISED");
                break;
    
            case WSAENETDOWN:
                puts("WSAENETDOWN");
                break;
    
            case WSAHOST_NOT_FOUND:
                puts("WSAHOST_NOT_FOUND");
                break;
    
            case WSATRY_AGAIN:
                puts("WSATRY_AGAIN");
                break;
    
            case WSANO_RECOVERY:
                puts("WSANO_RECOVERY");
                break;
    
            case WSANO_DATA:
                puts("WSANO_DATA");
                break;
    
            case WSAEINPROGRESS:
                puts("WSAEINPROGRESS");
                break;
    
            case WSAEFAULT:
                puts("WSAEFAULT");
                break;
    
            case WSAEINTR:
                puts("WSAEINTR");
                break;
    
            default:
                puts("Other error");
                break;
            }
        }
    
    EXIT_FUNC:
        WSACleanup();
    
        return 0;
    }


  • 実行結果
  • HostName: text.pmtpa.wikimedia.org
    h_length: 4
    h_addrtype: AF_INET
    h_aliases[0]: ja.wikipedia.org
    h_aliases[1]: text.wikimedia.org
    h_addr_list[0]: 208.80.152.2

    参考
    http://msdn.microsoft.com/en-us/library/ms738524.aspx