HttpWebRequest在对Web服务器的第二次调用中超时



我遇到了一个非常奇怪的问题:

Python Pasteweb服务器上有一个RESTfull web服务,WPF.net应用程序每2秒向服务器发出一个http POST请求。问题是,在对服务器的第二次调用中,请求超时!有时后来(比如第四次或第五次)再次要求工作,后来我又得到了这个"超时"的例外!

IntelliTrace显示ws2_32.dll:中存在阻止的操作

阻塞操作被对的调用中断WSA取消阻止呼叫

我使用asp.net模拟了IIS上的REST web服务器,但问题不再存在,所以我认为可能是Python服务器配置!但是当我在浏览器中发出请求时,Python Web服务器可以正常工作!

然而,我在.net客户端应用程序中尝试了不同的东西:

  • 我增加了ServicePoint的DefaultConnectionLimit:

    ServicePointManager.DefaultConnectionLimit = 500;

  • 我为服务器的任何新请求创建了一个新线程,并在请求完成后中止了它!

  • 我在任何请求之前创建了一个新的AppDomain,并在处理完成后显式卸载它!

  • 尝试了不同的http请求标头:connection=keep-alive, accept=*

以上似乎都不起作用!然而,有趣的是,当我在VS 2012中为GetRequestStream()行设置断点时,请求不会超时并正常工作!

使用反射调试.net托管代码我发现ws2_32.dll的非托管recv方法导致操作阻塞,因此web请求超时!

这是C#代码:

static void Main(string[] args)
{
Task.Run(() =>
{
while (true)
{
Thread.Sleep(2000);
Console.WriteLine(PostData());
}
});
Console.ReadLine();
}
public static string PostData()
{
try
{
var response = "";
var httpRequest = WebRequest.CreateHttp("http://remote_address");
httpRequest.ServicePoint.ConnectionLimit = 500;
httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded";
httpRequest.Timeout = 5000;
using (var writer = new StreamWriter(httpRequest.GetRequestStream()))
{
writer.Write("req=" + "[some parameters]");
}
using (WebResponse httpResponse = httpRequest.GetResponse())
{
using (var data = httpResponse.GetResponseStream())
{
StreamReader sr = new StreamReader(data, Encoding.UTF8);
response = sr.ReadToEnd();
}
httpResponse.Close();
}
return response;
}
catch (WebException ex)
{
return "time out!";
}
}

我能做些什么吗?

我设法通过禁用Expect100Continue标头来解决问题:

ServicePointManager.Expect100Continue = false;

根据HTTP 1.1协议,当发送该报头时,使用POST方法的客户端请求期望从服务器接收100-Continue响应,以指示客户端应该发送要发布的数据。

如果将此属性设置为true(这是.Net的默认行为),则数据不会与初始请求一起发送。相反,如果实现正确,则将此标头发送到web服务器,web服务器将以100-Continue进行响应。但是,并非所有web服务器都能正确处理此问题,包括我试图向其发布数据的服务器。我使用Fiddler嗅探了头部,注意到我的代码确实发送了这个头部,而Python Paste没有!

最新更新