4

Windows 2008x64 で C++ アプリケーションの 1 つに問題があります (同じアプリが Windows 2003x64 でも問題なく動作します)。

クラッシュ後、または通常のシャットダウン/再起動サイクルの後でも、コマンドを受信する必要があるポート 82 でソケットを使用すると問題が発生します。

netstat を見ると、アプリケーションが停止してから 10 分以上経過しても、ソケットがまだリッスン状態にあることがわかります (プロセスは確実に実行されていません)。

  TCP    0.0.0.0:82             LISTENING

ソケット オプションを REUSEADDR に設定しようとしましたが、私が知る限り、TIME_WAIT 状態のポートへの再接続にのみ影響します。いずれにせよ、この変更は何の違いもないように見えました。

int doReuse = 1;
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR,
           (const char *)&doReuse, sizeof(doReuse)); 

この問題を解決する、または少なくとも回避するために私ができることはありますか?

編集:

netstat -an を実行しましたが、取得できるのはこれだけです。

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING

netstat -anb の場合:

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING
 [System]

正常にシャットダウンすることは認識していますが、アプリが何らかの理由でクラッシュした場合でも、再起動できる必要があります。問題のアプリケーションは、Windows Sockets API を内部的に使用する社内ライブラリを使用しています。

編集:

どうやらこの問題の解決策はないようです。そのため、開発のためにプロキシ/ツールを使用して回避します。すべての提案に感謝します。

4

6 に答える 6

2

これがデバッグ時にのみ問題になる場合は、sysinternals 関係者の tcpview を使用て、ソケットを強制的に閉じてください。お使いのプラットフォームで動作すると思いますが、よくわかりません。

ソケットでブロッキング操作を行っている場合は、無期限のタイムアウトを使用しないでください。私の経験では、これはマルチプロセッサ マシンで奇妙な動作を引き起こす可能性があります。どの Windows サーバー OS かはわかりませんが、2003 Server よりも 1 つまたは 2 つ前のバージョンでした。無期限のタイムアウトの代わりに、30 ~ 60 秒のタイムアウトを使用してから、待機を繰り返します。これは、使用している場合、重複した IO および IOCompletion ポートにも当てはまります。

これが他の人が使用するために出荷しているアプリである場合は、頑張ってください。ソケットを使用する場合、Windowsは純粋なろくでなしになる可能性があります...

于 2010-12-17T04:29:50.067 に答える
1

ソケットオプションを REUSEADDR に設定しようとしましたが、私が知る限り、TIME_WAIT 状態のポートへの再接続にのみ影響します。

それはあまり正しくありません。これにより、TIME_WAIT 状態のポートをリッスンまたは接続などの目的で再利用できます。しかし、これでは役に立たないことに同意します。OS がクラッシュしたリスナーを検出するのに 10 分かかるというコメントに驚いています。プロセスが終了するとすぐに、TIME_WAIT 状態のポート以外のすべてのリソースをクリーンアップする必要があります。

于 2010-12-17T01:44:58.493 に答える
0

走る

netstat -ano

これにより、ポートが開いているプロセスのPIDがわかります。タスクマネージャからそのプロセスを確認してください。[すべてのユーザーのプロセスを一覧表示する]がオンになっていることを確認してください。

于 2010-12-17T00:34:12.333 に答える
0

最初に確認することは、実際にアプリケーションがそのポートでリッスンしていることです。使用する:

netstat -anb

そのポートでリッスンしているプロセスを特定します。

2 番目に確認することは、アプリケーションのシャットダウン時にソケットが適切に閉じられていることです。あまり問題にならない高レベルのソケット API を使用している場合 (ソケットAPI を使用していますよね?)。

最後に、アプリケーションはどのように構成されていますか? ねじ込み式ですか?他のプロセスを起動しますか? アプリケーションが本当にシャットダウンされていることをどのように確認しますか?

于 2010-12-16T20:51:26.367 に答える
0

http://hea-www.harvard.edu/~fine/Tech/addrinuse.htmlは、「Bind: Address Already in Use」エラーの優れたリソースです。

いくつかの抜粋:

TIME_WAIT は、通常、プロセスが完了してから数分間ポートが拘束される状態です。関連するタイムアウトの長さはオペレーティング システムによって異なり、一部のオペレーティング システムでは動的な場合がありますが、一般的な値は 1 ~ 4 分の範囲です。

回避のための戦略

SO_REUSEADDR

これは、「アドレスは既に使用されています」というエラーを減らすための最も簡単で効果的なオプションです。

クライアントが最初に閉じる

リモート エンドが閉鎖を開始する場合、TIME_WAIT を回避できます。そのため、サーバーはクライアントを最初に閉じることで問題を回避できます。

タイムアウトを減らす

(何らかの理由で) これらのオプションのいずれも機能しない場合は、TIME_WAIT に関連するタイムアウトを短縮することもできます。

于 2015-01-13T02:17:33.113 に答える