Использование .NET HttpWebRequest для загрузки множества файлов подряд - PullRequest
1 голос
/ 23 марта 2010

У меня есть приложение, которое должно загружать несколько файлов подряд (иногда несколько тысяч). Однако в конечном итоге происходит необходимость загрузки нескольких файлов: я получаю исключение с внутренним исключением типа SocketException и кодом ошибки 10048 (WSAEADDRINUSE). Я немного покопался, и в основном это потому, что на сервере закончились сокеты (и все они ждут около 240 секунд или около того, прежде чем они снова станут доступны) - не случайно это начинает происходить в диапазоне файлов 1024. Я ожидаю, что HttpWebRequest / ServicePointManager будет повторно использовать мое соединение, но, по-видимому, это не так (и файлы https, так что это может быть его частью). Я никогда не видел этой проблемы в коде C ++, из которого она была портирована (но это не значит, что этого никогда не было - хотя я бы удивился, если бы это было).

Я правильно закрываю объект WebRequest, а для объекта HttpWebRequest по умолчанию для KeepAlive установлено значение true. Следующее мое намерение - возиться с ServicePointManager.SetTcpKeepAlive (). Тем не менее, я не вижу, как больше людей не столкнулись с этой проблемой.

Кто-нибудь еще сталкивался с проблемой, и если так, что вы сделали, чтобы обойти это? В настоящее время у меня есть схема повторных попыток, которая обнаруживает эту ошибку и ожидает ее, но это не похоже на то, что нужно делать.

Вот некоторый базовый код для проверки того, что я делаю (на случай, если мне не хватает чего-то при закрытии):

WebRequest webRequest = WebRequest.Create(uri);
webRequest.Method = "GET";
webRequest.Credentials = new NetworkCredential(username, password);

WebResponse webResponse = webRequest.GetResponse();
try
{
    using(Stream stream = webResponse.GetResponseStream())
    {
        // read the stream
    }
}
finally
{
    webResponse.Close()
}

Ответы [ 2 ]

1 голос
/ 23 марта 2010

Что это за приложение?Вы упомянули, что на сервере заканчиваются порты, но затем вы упомянули HttpWebRequest.Вы запускаете этот код на странице веб-службы или ASP.NET, которая пытается затем загрузить несколько файлов для одного и того же входящего запроса от клиента?

Какой тип проверки подлинности используется страницей?Если он использует проверку подлинности NTLM, то соединения не могут быть общими, если используемые учетные данные различны для каждого запроса.

Я бы предложил сгруппировать ваш запрос по учетным данным.Так, например, все запросы с использованием имени пользователя «Джон» будут сгруппированы.Вы можете указать свойство «ConnectionGroupName» в точке обслуживания, чтобы система попыталась повторно использовать соединения для тех же учетных данных и сервера.

Если это также не работает, вам потребуется выполнить одно или несколько из следующих действий:следующее:

1) Отрегулируйте ваши запросы.

2) Увеличьте диапазон портов подстановочного знака.

3) Используйте BindIPConnectionCallback на ServicePoint, чтобы привязать его к не подстановочному знакупорт (то есть порт в диапазоне 1024-16384)

0 голосов
/ 23 марта 2010

Похоже, что дальнейшее копание указывает на то, что это возможно из-за аутентификации, а свойство UnsafeAuthenticatedConnectionSharing может смягчить это.Тем не менее, я не уверен, что это тоже самое лучшее.

...