Проблема с кодом запроса C # HTTP PUT - PullRequest
3 голосов
/ 23 августа 2011

Я пытаюсь отправить файл на S3 через URL запроса PUT, который Amazon S3 уже сгенерировал для меня.

Мой код отлично работает для небольших файлов, но он выдает ошибки для больших файлов (> 100 МБ) после нескольких минут отправки.

Есть ошибка: Запрос был прерван: Запрос был отменен. в System.Net.ConnectStream.InternalWrite (логический асинхронный, буфер Byte [], смещение Int32, размер Int32, обратный вызов AsyncCallback, состояние объекта) в System.Net.ConnectStream.Write (буфер Byte [], смещение Int32, размер Int32)

Может кто-нибудь сказать мне, что не так с моим кодом, который мешает ему отправлять большие файлы? Это происходит не по причине истечения срока действия URL-адреса запроса PUT Amazon, поскольку у меня установлено значение 30 минут, и проблема возникает после нескольких минут отправки.

Код в конечном итоге исключает из этой строки кода: dataStream.Write(byteArray, 0, byteArray.Length);

Еще раз, это прекрасно работает для небольших файлов, которые я отправляю на S3. Просто не большие файлы.

WebRequest request = WebRequest.Create(PUT_URL_FINAL[0]);
//PUT_URL_FINAL IS THE PRE-SIGNED AMAZON S3 URL THAT I AM SENDING THE FILE TO

request.Timeout = 360000; //6 minutes

request.Method = "PUT";

//result3 is the filename that I am sending                                     
request.ContentType =
    MimeType(GlobalClass.AppDir + Path.DirectorySeparatorChar + "unzip" +
             Path.DirectorySeparatorChar +
             System.Web.HttpUtility.UrlEncode(result3));

byte[] byteArray =
    File.ReadAllBytes(
        GlobalClass.AppDir + Path.DirectorySeparatorChar + "unzip" +
        Path.DirectorySeparatorChar +
        System.Web.HttpUtility.UrlEncode(result3));

request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();

// this is the line of code that it eventually quits on.  
// Works fine for small files, not for large ones
dataStream.Write(byteArray, 0, byteArray.Length); 

dataStream.Close();

//This will return "OK" if successful.
WebResponse response = request.GetResponse();
Console.WriteLine("++ HttpWebResponse: " +
                  ((HttpWebResponse)response).StatusDescription);

Ответы [ 4 ]

2 голосов
/ 24 августа 2011

Вам следует установить для свойства Timeout значения WebRequest более высокое значение.Вызывает тайм-аут запроса до его завершения.

2 голосов
/ 23 августа 2011

Используйте Fiddler или Wireshark , чтобы сравнить, что происходит по проводам, когда он работает (сторонние инструменты) и когда он не работает (ваш код) ... один раз Вы знаете различия, вы можете изменить свой код соответственно ...

1 голос
/ 24 августа 2011

Я бы попробовал записать его порциями и разбить массив байтов. Это может быть удушье на один большой кусок.

Примерно так:

        const int chunkSize = 500;
        for (int i = 0; i < byteArray.Length; i += chunkSize)
        {
            int count = i + chunkSize > byteArray.Length ? byteArray.Length - i : chunkSize;
            dataStream.Write(byteArray, i, count);
        }

Возможно, стоит еще раз проверить, чтобы все было написано, я провел только базовое тестирование.

0 голосов
/ 23 августа 2011

Просто приблизительное предположение, но разве вы не должны иметь:

request.ContentLength = byteArray.LongLength;

вместо:

request.ContentLength = byteArray.Length;

Подумав, 100 МБ = 100 *1024* 1024 <2 ^ 32, так что, вероятно, это не будет проблемой </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...