15

コードで:

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;

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

4

2 に答える 2

15

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

これは、警告が完全に間違っていることを意味します。getnameinfo() は gethostbyaddr() の代わりであり、どちらも IP→name 検索用です。逆。

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

新しい関数はさらに多くのことを実行できます。IPv6 を処理し「http」などの文字列を 80 (ポート) に変換できます。将来的には、問題のサービスに TCP を使用するか、SCTP を使用するかを決定することもできます。インターフェイスの準備が整いました。

于 2013-05-19T05:55:50.963 に答える
11

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,     // Hostname string buffer length
    service,         // Pointer to service name string
    sizeof service,  // Service name string buffer length
    0                // No flags given
);

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

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

十分なはずです。

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

于 2012-04-27T07:27:26.580 に答える