2017/02/21

[c/c++]gethostbyname()は過去のものだったのか

いつもESP8266で作るときはローカルでサーバを立てていたのでIPアドレスを直接書いていたのだが、名前解決するようにしておいたほうがよいよな、と思った。
RTOS SDKを使うようにするつもりなので、Linuxで試しておこう。

 

確か、名前からIPアドレスを取得するのは、gethostbyname()とかいう関数だったよな、と検索した。
Man page of GETHOSTBYNAME

出てきたものの、説明の1行目にこう書いてあった。

関数 gethostbyname*(), gethostbyaddr*(), herror(), hstrerror は過去のものである。
アプリケーションは、代わりに getaddrinfo(3), getnameinfo(3), gai_strerror(3) を使用すること。

なんですってー!
おじさん、驚愕である。


gethostbyname()を使ってもよいけど、今から調べるのに過去の人になる必要もないので、getaddrinfo()を調べた。

//https://linuxjm.osdn.jp/html/LDP_man-pages/man3/getaddrinfo.3.html
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
    int ret;
    struct addrinfo hints;
    struct addrinfo *ainfo;

    //IPアドレスを知りたいだけなんだ!
    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_family = AF_INET;

    ret = getaddrinfo("www.yahoo.co.jp", NULL, &hints, &ainfo);
    if (!ret) {
        struct addrinfo *rp;
        for (rp = ainfo; rp != NULL; rp = rp->ai_next) {
            struct sockaddr_in *in = (struct sockaddr_in *)rp->ai_addr;
            printf("addr    : %s\n", inet_ntoa(in->sin_addr));
        }
        freeaddrinfo(ainfo);
    } else {
        printf("ERR: %s\n", gai_strerror(ret));
    }
    return 0;
}

$ gcc -Wall -o tst getaddrinfo.c
$ ./tst
addr    : 182.22.40.240
addr    : 182.22.59.229
addr    : 182.22.63.230
addr    : 183.79.111.124

出たけどさ、やりたいことに比べて実装が多くないかい?
まあ、IPv6やらなんやらあるので、こうなったのかもしれんが。

 

これをコンパイルしているときに気付いたのだが、gccで「-std=c99」オプションを付けると、いろいろ見えなくなってコンパイルエラーになるのだ。
struct addrinfoが見えなくて、hintsがわからんとか言われるし。
C99でチェックが厳しくなったとかじゃないし、なんだろう?
またBash on Windowsだからとかだろうか?

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。