http サーバーとの通信に WebClient オブジェクトを使用するコードをローカルでテストする必要があります。そのために、バイナリ ファイルから数バイトを読み取ってクライアントに送信する、非常に単純なモック サーバーを作成することにしました。関連するサーバーのコードは次のとおりです。
public void Listen()
{
TcpClient client;
NetworkStream netStream;
listener.Start();
try
{
client = listener.AcceptTcpClient();
netStream = client.GetStream();
ReadData(netStream);
Console.WriteLine("Writing data, sequence 1");
WriteData(netStream, 1);
netStream.Close();
client.Close();
client = listener.AcceptTcpClient();
netStream = client.GetStream();
ReadData(netStream);
Console.WriteLine("Writing data, sequence 2");
WriteData(netStream, 2);
netStream.Close();
client.Close();
}
catch(Exception e)
{
}
}
private void WriteData(NetworkStream netStream, int sequence)
{
byte[] bytes = PrepareResponse(sequence); //get data from a file
netStream.Write(bytes, 0, bytes.Length);
}
WebClient では UploadString を使用します。
string response = client.UploadString(address + link, data);
つまり、WebClient は明らかに送信されたすべてのデータを受信しますが、ストリーム サーバー側を閉じると System.IO.Exception (「トランスポート接続からデータを読み取れません: 接続が閉じられました。」) がスローされます。ストリームを閉じないと、すべてのデータが受信されているにもかかわらず、WebClient はブロックされ、転送が完了するのを待ちます。WebClient を WebRequest に置き換えようとしましたが、ソケットがサーバー側で閉じられている場合は例外がスローされるか、すべてのデータを読み取った後に stream.Read でブロックされます。私が奇妙に思うのは、WebClient に送信するデータの最初のブロックが http 302 "Moved" 応答であり、WebClient がすぐに GET 要求を送信することです。同じようにデータを 2 回送信したにもかかわらず、WebClient は 2 回目の応答でのみ例外をスローします。
したがって、データを正しく送信して接続を閉じて WebClient で動作するようにする方法が必要です。また、WebClient が 302 応答を正しく処理し、2 番目の応答で例外をスローする理由も知りたいです。
ありがとうございました。