я следующий код, который загружает файл на сервер, сделав запрос POST:HttpWebRequest - отправка файла кусками и отслеживания прогресса
string fileName = @"C:\Console_sk.txt";
HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create("http://" + Environment.MachineName + ":8000/Upload");
request.Method = "POST";
request.ContentType = "text/plain";
request.AllowWriteStreamBuffering = false;
Stream fileStream = new FileStream(fileName, FileMode.Open);
request.ContentLength = fileStream.Length;
Stream serverStream = request.GetRequestStream();
byte[] buffer = new byte[4096];
while (true)
{
int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
serverStream.Write(buffer, 0, bytesRead);
}
else
{
break;
}
}
serverStream.Close();
fileStream.Close();
request.GetResponse();
Это будет использоваться для загрузки потенциально больших файлов, поэтому для нас важно отслеживать ход этой загрузки.
Основываясь на various sources, я думал, что мой код будет загружать файл в 4096 байтовых кусках, т. Е. Будет сделано несколько запросов POST. Но при отслеживании запросов с помощью Fiddler это показывает, что сделан только один запрос POST. С другой стороны, когда я включил .NET network tracing, результирующий журнал показал, что 4096 байтовых блоков действительно записаны для запроса потока, и сокет всегда открывается для каждой операции записи.
Мое понимание сети в целом довольно плохое, поэтому я не совсем понимаю, как это действительно работает. При вызове serverStream.Write
, предоставленный кусок действительно отправлен по сети, или он просто буферизуется где-то? И когда вызывается serverStream.Close
, могу ли я быть уверенным, что весь файл был загружен?
Благодарим за это. Как насчет моего второго вопроса относительно 'serverStream.Close'? –
Когда вы закрываете поток запросов, все данные будут записаны в сокет. На самом деле вы не должны закрывать эти IDisposable ресурсы вручную, как и вы. Вы должны обернуть их в выражения 'using', чтобы обеспечить правильное удаление даже в случае ошибки. –
Хм, теперь я снова смущен :). Сначала вы написали, что кусок записывается в сокет, когда вызывается 'Write'. Теперь вы говорите, что все данные будут записаны в сокет, когда вызывается 'Close'. Я был бы очень благодарен, если бы вы могли объяснить все это в более простых выражениях, возможно, что-то еще не хватает. Спасибо, что нашли меня здесь! –