TCP/IP Windows 7ループバックアダプター(またはソフトウェアのバグ?)のパケット遅延に関する問題

StackOverflow https://stackoverflow.com/questions/5321542

質問

現在、同じWindows 7 64ビットマシンでテストしているクライアントとサーバーのアプリケーションがあります。どちらもC#で書かれており、P/Invokeを使用してWinSock2ライブラリに呼び出します。

アプリケーションは、エラーがあれば全体的に正常に機能します。 TCP/IP上の各「ホップ」のレイテンシーは、平均で約350マイクロ秒です。

ただし、パケットを受信する前に40〜50m以上の非常に長い遅延があり、突然到着します。

これまで診断する努力:

  1. これらの遅延データを受信する間、サーバーはパケットを送信していることを記録し続けます。 1ミリ秒ごとにテストパケットを送信するように設定されています。これは、クライアントがそれらのいずれかを受信する前に15または20で行うことがあります。

  2. TCPDUMPは、ループバックアダプターのパケットをスニッフィングするために使用され、このラグ期間中、サーバーポート(6488)からクライアントポート(61743)へのトラフィックが通常どおりにあることを示しています。

  3. クライアントは、select()winsock2呼び出しをループで呼び出すため、select()コールの前にカウンターを介してログインして、正しいファイル記述子があることが示されています。そしてもちろん、これは遅延の前後にうまく機能します。

  4. Select()コールの直後にさらにログすると、FDが存在しないことがわかります。つまり、ソケットの読み取りがブロックされることを意味します。ただし、遅延がある送信期間中、ロギングは、Select()がソケットのFDを返して非ブロッキング読み取りを実行するように、予想どおりに機能することを示しています。

要するに、ループバックアダプターはこれらのパケットを長い間どこかに保持しているように見えますが、最終的に受信側に配信します。

それ以上のアイデアや解決策はありますか?

いくつかの考えは、Windowsで重複したI/Oはよりよく機能すると主張することがよくありますが、64を超えるソケットを聞く必要がある場合にのみ重要であるように思われます。

オーバーラップに切り替えるとトリックが行われる可能性がありますか?プロジェクトの締め切りと予算が増加するため、避けたいと思います。これは、select()で正常に動作するはずです。

また、ループバックを処理するWindowsのプロセスまたはスレッドがコンテキストが切り替えられるなど、その場合、それらの遅延を回避するために構成する方法がありますか?

編集:正解は、ナグルアルゴリズムが無効になっていることを確認することでした。私たちはそれが無効になっていると考えましたが、それがバグが見つかった場所です - setsocketoption()の社内実装()を使用して検証しました。そのため、ソケットを接続またはバインドする前にNodelayを設定する必要があることがわかります。そうしないと、静かに効果がありません。

正解をありがとうMun Piengに感謝します!!!

役に立ちましたか?

解決

これが原因である可能性があると思います ナグルアルゴリズム. 。次のコードはそれを無効にします:

socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top