2009-07-17 7 views
1

背景:CreateIoCompletionPort、WSASend/Recv、およびGetQueuedCompletionStatusを使用して、サーバー上で重複したソケットioを実行しています。フロー制御では、クライアントに送信するときに、保留中のすべてのOVERLAPがIOCPからポップしたときにのみ、いくつかのWSASend()を呼び出すことができます。WSASendを使用している一部のオーバーラップが、GetQueuedCompletionStatusを使用してタイムリーに返されませんか?

問題:最近、OVERLAPがIOCPに返されない場合があります。 GetQueuedCompletionStatusを呼び出すスレッドはそれらを取得せず、ローカルの保留中のキューに残ります。クライアントがソケットからデータを受信し、ソケットが接続されていることを確認しました。 WSASend()呼び出しが行われたときにエラーは返されませんでした。重複するが、単純に次のような外部刺激せずに戻って来ない「決して」:

  1. クライアントまたはサーバからのソケットを切断、すぐに)GetQueuedCompletionStatusスレッドがのWSASend(への追加の呼び出しを作る重なっ
  2. を取得することができます場合によっては、いくつかのOVERLAPが突然キューから飛び出す前に、いくつかが必要になることがあります。

質問:このタイプの動作を見た人はいますか?これを引き起こしていることに関するアイデアはありますか?

おかげで、 ジェフリー

+0

あなたのアプリはシングルまたはマルチスレッドですか? – zdan

+0

マルチスレッドです。 1つのスレッドはループし、GetQueuedCompletionStatusを呼び出し、OVERLAPをリサイクルします。また、別のスレッドはWaitForSingleObject(短いタイムアウト100ms)を使用し、イベントが設定されていればWSASend()を呼び出します。 –

答えて

3

WSASend()は、TCPウィンドウがいっぱいになった場合は、適時に完了しないことができます。この場合、スタックはそれ以上のデータを送信できないので、WSASend()が待機し、TCPスタックがより多くのデータを送信できるようになるまで完了しません。

フロー制御がプロトコル自体に組み込まれておらず、書き込み完了に基づいてフロー制御を自分で行っておらず、サーバーと同じ速さでデータを送信しているだけのクライアントとサーバーの間にプロトコルがある場合あなたがネットワークまたはクライアントのいずれかが追いつくことができず、TCPフロー制御が開始される(TCPウィンドウがいっぱいになった)時点に到達する可能性があります。 WSASend()への追加呼び出しで非同期にデータを非同期的に切断し続けると、マシン上のページングされていないメモリをすべて掘り下げ、その時点ですべてのベットがオフになります(ドライバが発生する可能性が高い青写真へのボックス)。

要するに、重複したソケット書き込みからの補完は、予想よりも戻ってくることがあります。あなたの例では、ソケットを閉じるときに得られる補完はすべて失敗であると思いますか?

私のブログでこれについてもう少し話します。ここに:http://www.lenholgate.com/blog/2008/07/write-completion-flow-control.htmlとここに:http://www.serverframework.com/asynchronousevents/2011/06/tcp-flow-control-and-asynchronous-writes.html

関連する問題