Windows XPで、ノンブロッキング ソケットで繰り返しWSASendを呼び出すと、WSAENOBUFS で失敗します。
ここには2つのケースがあります:
ケース 1:
ノンブロッキング ソケットでは、WSASendを呼び出しています。擬似コードは次のとおりです。
while(1)
{
result = WSASend(...); // Buffersize 1024 bytes
if (result == -1)
{
if (WSAGetLastError() == WSAENOBUFS)
{
// Wait for some time before calling WSASend again
Sleep(1000);
}
}
}
この場合、WSASend は約 88000 回正常に戻ります。次に、WSAENOBUFS で失敗し、コードに示されているように、しばらくしてから試行しても回復しません。
ケース 2:
この問題を解決するために、私はこれを参照し、そこで提案されているように、上記のコードの直前に、SO_SNDBUF を指定してsetsockoptを呼び出し、バッファーサイズを 0 (ゼロ) に設定しました。
この場合、WSASend は約 2600 回正常に戻ります。その後、失敗します。しかし、2600回待った後、再び成功し、失敗します。
今、私は両方のケースでこれらの質問をしています:
ケース 1:
- ここでこの88000という数字を決定する要因は何ですか?
- 失敗の原因が TCP バッファがいっぱいだった場合、しばらくして回復しなかったのはなぜですか?
ケース 2:
- 繰り返しますが、ここで 2600 という数字を決定する要因は何ですか?
- Microsoft KB 記事にあるように、内部 TCP バッファの代わりにアプリケーション バッファから直接送信すると、WSAENOBUFS で失敗するのはなぜですか?
編集:
非同期ソケット (Windows XP の場合) の場合、動作はさらに奇妙になります。WSAENOBUFS を無視してさらにソケットへの書き込みを続けると、最終的に WSAECONNRESET が切断されます。そして、なぜそれが起こるのか、現時点ではわかりませんか?