GetRequestStream(またはBeginGetRequestStream)を呼び出す前にContentLengthプロパティを設定し、そのストリームに書き込むバイト数を減らします。リクエストストリームを取得した後にContentLengthを設定しようとすると、ContentLengthがスローされます。 ContentLengthを設定しない場合、HttpWebRequestは、ストリームが閉じられてContentLengthを適切に設定できるようになるまで、ヘッダーをバッファします(代わりに、SendChunkedを使用できますが、ここでは機能しません)。これを最大限に制御したい場合は、1つまたは2つの不正なリクエストを手作業で作成し、サーバー上のポート80へのソケットを開き、TCPストリームに要求を書き込み、応答を読み取り、接続が閉じられているかどうかを確認します。 。
ただし、このテストは良い考えではないと思います。問題は次のとおりです。
クライアントからサーバーに要求が送信されます。内容は100バイトと主張しています。次に、90バイトを送信し、送信を停止して接続を開いたままにします。サーバーは90バイトを読み取り、クライアントが100バイトが送信されると言い、残りを待ちます。今、クライアントは2番目の要求を送信します。サーバーは新しいリクエストの最初の10バイトで何をしますか?
答えは、サーバーが前の要求の一部であると仮定し、そのように処理した後、開始から10バイト後に「新しい」要求を読み始めることです。これは明らかに不正なヘッダーになります。サーバーはそれを好まないので、4xxエラーを送信して接続を終了します。接続を閉じる理由は、現在送信されているデータが何を意味するのか、回復する方法がわからないためです。また、接続の終了は正常ではなく、突然になり、2番目のリクエストを送信している相手側のHttpWebRequest(またはキューに入れられている場合は3番目または4番目)がWebExceptionをスローします基本的な接続は閉じられ、なぜあなたは推測のままになります。
これは、接続がExpect 100-continueヘッダーで閉じられ、サーバーがAuthが必要な場合など、100-continueの後に4xxを返した場合に発生します。要求を拒否したとしても、100バイトを送信してこれらのバイトを受信することを約束しているので、次のバイトが同じ要求の一部であると仮定しなければならない。その要求を処理できない場合や、クライアントが要求をキャンセルして新しい認証情報を送信したい場合は、接続を閉じて新しいものを開く必要があります。
最後に、TCPを使用してネットワークストリームからEndOfStreamExceptionをテストしても、まったく意味がありません。 TCPはストリームの「終わり」をマークせず、ソケットに書き込まれるときにデータを送信し続けるだけです。それには「EOF」はなく、期待するデータ量を知らない限り、データがすべて送信されたかどうかを検出する方法はありません。接続が閉じられていない限り、TCPは実際にストリームの「終わり」を持っていません。この場合、スタック内のどこかに応じてWebExceptionまたはSocketExceptionが発生します。プロトコル内の送信エラーはすべて、winsockで処理されます。それ以上のデータが送信されない場合、接続の一方の端は結局キープアライブを他方に送信して、接続が実際に開いており、1つのホストだけがドロップしていないことを確認します。キープアライブがタイムアウトすると、接続が閉じられ、次回から読み込みを試みるときにWebExceptionが発生する可能性があります。どのように動作するかを考えれば、このテストからどのような価値を得るのか分かりません。不正なリクエストを送信し、エラーが適切に処理され、適切な4xxメッセージがクライアントに返され、接続が適切に閉じられていることを確認するほうがはるかに優れています。
統合テストでは、クライアントをシミュレートします。テストを容易にするために受信側を変更することはできません。 – cfeduke