使用.NET的HttpWebRequest连续下载大量文件

时间:2010-03-23 00:09:02

标签: c# httpwebrequest socketexception

我有一个应用程序需要连续下载几个文件(有时几千个)。但是,当需要下载多个文件时最终发生的事情是我得到一个异常,其中包含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 个答案:

答案 0 :(得分:1)

这是什么类型的应用程序?您提到服务器的端口不足,但之后您提到了HttpWebRequest。您是否在Web服务或ASP.NET页面中运行此代码,该页面尝试从客户端下载同一传入请求的多个文件?

页面使用什么样的身份验证?如果它正在使用NTLM身份验证,则如果正在使用的凭据对于每个请求都不同,则无法共享连接。

我建议将每个凭据的请求分组。因此,例如,使用用户名“John”的所有请求都将被分组。您可以在服务点上指定“ConnectionGroupName”属性,因此系统将尝试重用同一凭据和服务器的连接。

如果这也不起作用,您将需要执行以下一项或多项操作:

1)限制您的请求。

2)增加通配符端口范围。

3)使用ServicePoint上的BindIPConnectionCallback使其绑定到非通配符端口(即1024-16384范围内的端口)

答案 1 :(得分:0)

更多挖掘似乎指出它可能是由于身份验证而且UnsafeAuthenticatedConnectionSharing属性可能会缓解这种情况。但是,我不确定这是最好的事情。