このコードの欠陥を指摘できる人はいますか? TcpClient で HTML を取得しています。IIS サーバーとの通信中に NetworkStream.Read() が終了しないようです。代わりに Fiddler プロキシを使用すると問題なく動作しますが、ターゲット サーバーと直接通信すると、「リモート サーバーが接続を閉じました」などのエラーで接続例外が発生するまで、.read() ループは終了しません。
internal TcpClient Client { get; set; }
/// bunch of other code here...
try
{
NetworkStream ns = Client.GetStream();
StreamWriter sw = new StreamWriter(ns);
sw.Write(request);
sw.Flush();
byte[] buffer = new byte[1024];
int read=0;
try
{
while ((read = ns.Read(buffer, 0, buffer.Length)) > 0)
{
response.AppendFormat("{0}", Encoding.ASCII.GetString(buffer, 0, read));
}
}
catch //(SocketException se)
{
}
finally
{
Close();
}
アップデート
デバッガーでは、応答全体がすぐに送信され、StringBuilder (応答) に追加されていることがわかります。サーバーが応答の送信を完了したとき、または私のコードがそれを検出していないときに、接続が閉じられていないように見えます。
結論 ここで述べたように、トランザクションがいつ完了するかを判断するには、プロトコル (HTTP の場合は Content-Length ヘッダー) の機能を利用するのが最善です。ただし、すべてのページに content-length が設定されているわけではないことがわかりました。だから、私は今ハイブリッドソリューションを使用しています:
すべてのトランザクションの場合、リクエストの
Connection
ヘッダーを「close」に設定して、サーバーがソケットを開いたままにしないようにします。これにより、サーバーがリクエストへの応答中に接続を閉じる可能性が向上します。が設定されている場合
Content-Length
は、それを使用してリクエストがいつ完了するかを判断します。それ以外の場合は、NetworkStream の RequestTimeout プロパティを 1 秒などの大きな、しかし妥当な値に設定します。
NetworkStream.Read()
次に、 a) タイムアウトが発生するか、b) 要求したよりも少ないバイト数を読み取るまでループします。
すばらしい詳細な回答をくださった皆さんに感謝します。