2

ソケットを使用する移植可能な Windows/Linux アプリケーションを作成しています。関数を使用gethostbynameして DNS ルックアップを実行します。gethostbynameただし、タイムアウトを設定し、名前の検索中にアプリケーションがハングしないように保護する方法がわかりません。もちろん走行可能ですgethostbyname別のスレッドで、それが私がしていることです。ただし、これは単純なアプリケーションのみのソリューションです。私のアプリケーションは、1000 ~ 3000 の接続を並行して使用しています。このような状況で問題になるのは、タイムアウトになったスレッドをどうするかということです。良い解決策がわかりません。それらを「忘れる」ことはできますが、悪いネットワークではプログラムのスレッド数が無限に増えるリスクがあります。それらを終了することはできますが、その考えはひどいようです。私の経験からすると、何千ものスレッドが終了すると Windows がクラッシュする可能性があり、そのような状況で Linux がどのように動作するかはわかりません。また、スレッドの作成には多くのリソースが必要です。実行するためだけに 3000 のスレッドを作成するのは得策ではありませんgethostbyname機能して終了します。したがって、別のスレッドは、本当に複雑なアプリケーションには適していないように見えます。別の方法として、もちろん独自の DNS クライアントを作成することもできますが、これも見栄えがよくありません。カスタムタイムアウトでホストアドレスを取得するための Windows と Linux (またはより移植性の高い方法) で「公式」の方法はありますか?

4

2 に答える 2

2

まず第一に: は使わないgethostbyname()でください。時代遅れです。getaddrinfo()代わりに使用してください。

必要なのは、非同期の名前解決です。これは一般的な要件ですが、残念ながら「標準的な」方法、つまりそれを行う方法はありません。あなたに最適なソリューションを見つけるための私のヒントは次のとおりです。

  1. DNS クライアントを実装しないでください。名前解決は単なる DNS ではありません。mDNS、hosts ファイルなどを考えてみてください。getaddrinfo()さまざまな名前解決メカニズムを抽象化するようなシステム関数を使用します。

  2. 一部のシステムは、glibc offers のように、解決関数の非同期バージョンを提供していますgetaddrinfo_a()

  3. 同期システム リゾルバー関数をラップする非同期解決ライブラリがあります。最初にlibasyncnsが頭に浮かびます。

  4. Boost.Asio は、スレッド プールでのリゾルバーの使用をサポートしています。ここを参照してください。

于 2014-06-25T14:44:10.487 に答える
1

実際、最も移植性の高いソリューションは、名前解決に別のスレッドを使用することです。これはMSDNにも記載されています。

非同期の名前検索を実行する移植性のないソリューションが存在します。

Linux glibc 2.2.3+: getaddrinfo_a

Windows: WSAAsyncGetHostByName IPv4 のみ :(

非同期 DNS ライブラリが存在します。たとえば、 TADNSは十分に簡単に見えます。

于 2014-06-25T08:54:07.630 に答える