getaddrinfo
andを使用してホスト名情報を決定し、失敗した場合はandgetnameinfo
にフォールバックする古いコードを調べています。gethostname
gethostbyname
getnameinfo
さて、これは私には間違っているようです。推奨事項を作成できるように、コードの意図を理解しようとしています。長くて複雑なので、コード全体をここに再投稿したくはありませんが、要約してみます。
私が知る限り、このコードのポイントは、リッスンしているソケットに接続するために別のプロセスで使用できる文字列を生成することです。これは、ローカル プロセスだけでなく、リモート ホストがこのコンピュータに接続し直すためのものでもあるようです。
したがって、問題のコードは基本的に次のことを行っています。
getaddrinfo(node = NULL, service = port, hints.ai_flags = AI_PASSIVE, ai);
socket()
-- これは、で使用できるの可能な引数のリストを取得しbind()
ます。- 結果のリストを調べて、ソケットを作成します。
- 初めてソケットが正常に作成されたとき、これは「使用済み」として選択され
addrinfo
ます。 ai_addr
選択したのaddrinfo
を呼び出しgetnameinfo()
て、関連するホスト名を取得します。- これが失敗した場合は、 を呼び出して、結果
gethostname()
を調べますgethostbyname()
。
これが間違っていると思う理由はいくつかありますが、私の論理を検証したいと思います。まず、いくつかの実験から、getnameinfo()
ここではほぼ常に失敗しているようです。入力アドレスは宛先ではなくリッスン ソケットであるため、不明であると思われます。この観点からは、有効な IP は必要ありません。次に、結果を呼び出しgethostname()
て渡すと、ほとんどの場合、それ自体gethostbyname()
と同じ結果が返さgethostname()
れます。つまり、ローカル ホスト名を確認しているだけで、私には無意味に思えます。これは、必ずしもリモート ホストで使用できるとは限らないため、問題がありますね。
どういうわけか、サブネット上の自分のホスト名を特定しようとする全体的な考えはそれほど役に立たない可能性があると思いますが、別のホストにメッセージを ping して、ホストがどの IP アドレスを認識しているかを確認する必要があります。(残念ながら、このコンテキストでは意味がありません。プログラムのこのレベルで他のピアを知らないためです。)たとえば、ローカルホストには複数のNICがあり、したがって複数のIPアドレスがある可能性があるため、特定しようとしています単一のホストとアドレスのペアは無意味です。(すべての結果bind()
を同時にリッスンするのが正しい解決策ですか?) addrinfo
また、名前を に渡してフラグgetaddrinfo()
を設定するだけで名前を解決できることにも気付きました。つまり、ステップが冗長になる可能性があります。ただし、アプリオリにホスト名を提供せずに、ホスト名のある種の公平なビューを決定しようとしているため、ここではこれが行われていないと思います。もちろん、それは失敗し、とにかく使用することになります! また、「localhost」を に提供しようとしましたが、Linux ではホスト名が ai_canonname` に報告されますが、OS X では「localhost」になるだけなので、これはクロスプラットフォームであると想定されているため、あまり役に立ちません。AI_CANONNAME
getnameinfo()
gethostname()
getaddrinfo()
要約すると、私の質問は、最新のソケットプログラミングで、サブネットピアにアナウンスできるローカルホスト名を取得する正しい方法が存在する場合、どうすればよいですか? このコードを単純に の結果を返すように置き換えることに傾いていますがgethostname()
、 のような最新の呼び出しを使用したより適切な解決策があるかどうか疑問に思っていますgetaddrinfo()
。
これを行う方法がないと答えた場合は、gethostname()
ここで何かを返す必要があるため、とにかく使用する必要があります。そうしないと、API が壊れてしまいます。