1

この問題は断続的であり、30 秒ごとに実行され、次のネットワーク通信を実行するプロセスで数時間ごとに発生します。

  • リッスンしているリモート マシン上にサーバーがあります
  • クライアントはこのマシンに接続し、サーバーに再度接続するように指示します
  • サーバーはソケットを閉じ、クライアントに再接続します
  • クライアント側でソケットが閉じられると、クライアントはすぐに同じポートでリッスンを開始します

クライアントが同じポートでリッスンを開始しようとすると、JVM_Bind エラーがクライアントで発生しますが、元のソケットが閉じられた後にのみ開始しようとします。ソケットを閉じてから新しいソケットを開くまでに 100 ミリ秒のわずかな遅延を追加すると、JVM_Bind エラーが回避されます。

このシナリオをデバッグするには、どのツールを使用できますか? 連続 netstat を実行しても、ポートに干渉するものは何も表示されませんでした。

同じポートでリッスンする新しいソケットを開始するのは一種の悪い考えですが、なぜこのエラーが断続的に発生するのでしょうか?

編集:いくつかの追加情報。サーバーは、サーバー上の一時ポートからクライアントに接続します。クライアントの古いソケットはすぐに CLOSED になり、再度開くことができるはずです。考えられる原因は、OS、JVM、またはハードウェアで何かが起こっているのではないでしょうか?

4

2 に答える 2

1

この問題をいじった後、最終的に Wireshark と Procmon を実行して、TCP 接続とパケットを監視しました。Procmon は、Windows での問題をデバッグするための非常に優れたツールであり、TCP 接続がいつ作成され、いつドロップされるかを表示するように構成できます。Wireshark は、回線を通過する実際のパケット データを示します。この出力は、JVM_Bind エラーが発生したときに、物事が正常に進行していたことを示しています。機能したときと失敗したときのログに大きな違いはありませんでした。

これは、システムに責任があることを示しています。システム設定について考えた後、ドライバーの問題の可能性に注意を向けました。ネットワーク アダプタ ドライバを更新したところ、問題は解消されました。

この話の教訓は、Wireshark と Procmon を使用してネットワークの問題をデバッグすることであり、この問題を分析可能なものに変えました。

于 2012-11-05T20:36:40.563 に答える
1

ドキュメントから

TCP 接続が閉じられると、接続が閉じられた後、しばらくの間、接続がタイムアウト状態のままになることがあります (通常、TIME_WAIT 状態または 2MSL 待機状態と呼ばれます)。既知のソケット アドレスまたはポートを使用するアプリケーションの場合、ソケット アドレスまたはポートを含むタイムアウト状態の接続がある場合、必要な SocketAddress にソケットをバインドできない場合があります。

この状態になる理由については、こちらで詳しく説明しています。

これが TIME_WAIT 状態に入る方法です

これは、ソケットを切断するたびに発生するわけではないため、問題が断続的に発生する可能性があります。

bind(SocketAddress) を使用してソケットをバインドする前に SO_REUSEADDR を有効にすると、前の接続がタイムアウト状態であってもソケットをバインドできます。

socket.setReuseAddress(true);
于 2012-07-06T13:37:11.023 に答える