1

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

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

  1. クライアントまたはサーバーからソケットを切断すると、すぐに GetQueuedCompletionStatus スレッドが OVERLAP を取得できるようになります。
  2. すべての OVERLAP が突然キューから取り出される前に、WSASend() を追加で呼び出す必要があります。

質問: この種の行動を見た人はいますか? これを引き起こしている原因についてのアイデアはありますか?

ありがとう、ジェフリー

4

1 に答える 1

4

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

于 2009-12-02T13:53:27.277 に答える