web-dev-qa-db-ja.com

gethostbynameの代わりにgetnameinfoを使用する方法は?

コード内:

if ((Host = (struct hostent*) gethostbyname(address) ) == 0) // address is a string

4.5.x gccでクロスコンパイル(汎用アームアーキテクチャ)すると警告が表示されます:

(.text+0x1558): warning: gethostbyname is obsolescent, use getnameinfo() instead.

getnameinfo は:

int WSAAPI getnameinfo(
  __in   const struct sockaddr FAR *sa,
  __in   socklen_t salen,
  __out  char FAR *Host,
  __in   DWORD hostlen,
  __out  char FAR *serv,
  __in   DWORD servlen,
  __in   int flags
);

そしてそれはより多くのパラメータを取得しました...そして私はそれと混同しています、gethostbynameが機能していたのでそれが機能する必要があります。 gethostbynameの場合のように単純な愚かさを保つために渡すパラメーターは何ですか?

最後にここに私の試みがあります:

struct sockaddr_in servAddr;
struct hostent *Host;        /* Structure containing Host information */

/* open socket */
if ((handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    return LILI_ERROR;

memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family      = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(address.ptr());
servAddr.sin_port        = htons(port);

char servInfo[NI_MAXSERV];
if ( ( Host = (hostent*) getnameinfo(
                 (struct sockaddr *) &servAddr
                 ,sizeof (struct sockaddr)
                 ,address.ptr(), address.size()
                 ,servInfo, NI_MAXSERV
                 ,NI_NUMERICHOST | NI_NUMERICSERV )  ) == 0)
    return LILI_ERROR;

if (::connect(handle, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
    return LILI_ERROR;

それはうまくコンパイルされ、起動時にセグメンテーション違反はありませんが、サーバーを接続できません:(

15
cnd

gethostbyname()は名前→IPルックアップを行います。 getaddrinfo()に置き換える必要があります。これは同じことができます。

これは、警告が完全に間違っていることを意味します。 getnameinfo()は、IP→nameルックアップの両方でgethostbyaddr()の代わりになります。逆。

名前→IP:gethostbyname()getaddrinfo()
IP→名前:gethostbyaddr()getnameinfo()

新しい関数はさらに多くのことを実行できます。IPv6を処理し、は「http」のような文字列を80(ポート)に変換できます。将来的には、彼らはまた、例えばTCPは、問題のサービスまたはSCTPに使用する必要があります。インターフェイスの準備ができています。

13
Robert Siemer

Beej'sはそれをかなり良いと説明しています。 gethostbyname() はIPV6ではうまく機能しないため、代わりに getnameinfo() を使用する必要があります。あなたがしなければならないのは、必要な情報を記入することです。

getnameinfo(
    &sa,             // Pointer to your struct sockaddr
    sizeof sa,       // Size of this struct
    Host,            // Pointer to hostname string
    sizeof Host,     // Size of this string
    service,         // Pointer to service name string
    sizeof service,  // Size of this string
    0                // No flags given
);

編集:いくつかの調査の後、私はそれを発見しました

getnameinfo(&sa, sizeof(sa), hostname, size_hostname, NULL, NULL, 0);

十分なはずです。

編集#2ホスト名としてgetnameinfoの戻り値を使用しようとしていることに気づきました。しかし、それは正しくありません。ホスト名は、提供されたHostポインター内に保存されます。戻り値は、操作が十分であったかどうかを示します。 manページ もご覧ください。

11