我正在开发一个C#应用程序,该应用程序可登录Web服务器的数据。它将以下帖子请求发送给Web服务器,并等待响应。
/// <summary>
/// Function for obtaining testCgi data
/// </summary>
/// <param name="Parameters"></param>
/// <returns></returns>
private string HttpmyPost(string Parameters)
{
string str = "No response";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriTestCGI);
request.Method = "POST";
byte[] bytes = Encoding.UTF8.GetBytes(Parameters);
request.ContentLength = bytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
WebResponse response = request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
try
{
var result = reader.ReadToEnd();
stream.Dispose();
str = result.ToString();
reader.Dispose();
}
catch (WebException ex)
{
//System.Windows.Forms.MessageBox.Show(ex.Message);
System.Diagnostics.Trace.WriteLine(ex.Message);
}
finally
{
request.Abort();
}
return str;
}
我正在遇到错误
> "The underlying connection was closed: The connection was closed
> unexpectedly"
我试图调试错误,并且我使用了提琴手来检查Firefox给出的发布请求。让我感到惊讶的是,每当提琴手是我的程序运行良好时。当我关闭提琴手时,我遇到了同样的错误。
我怀疑,既然提琴手都充当代理人,它可能会改变某些设置。我尝试使用WebClient,结果是相同的。
当我尝试在Python中编码请求时,一切都应该毫无问题地奏效。我可以选择安装Ironpython并包装特定的功能,但是我认为这种过度杀伤和缺乏优雅,因此我正在采用更精益的方法。我怀疑这不仅仅是设置调整。
我尝试修改,就我而言,这是无动于衷的。
request.Accept
request.ReadWriteTimeout
request.Timeout
request.UserAgent
request.Headers
request.AutomaticDecompression
request.Referer
request.AllowAutoRedirect
//request.TransferEncoding
request.Expect
request.ServicePoint.Expect100Continue
request.PreAuthenticate
request.KeepAlive
request.ProtocolVersion
request.ContentType
在有或没有上述调整的情况下,Fiddler捕获数据时代码有效。
也可能值得注意的是,该程序在
上产生错误WebResponse response = request.GetResponse();
更新:遵循@ericlaw的建议,我调查了延迟。我找到了这篇文章添加一个间隔时,httpwebrequest的速度较慢这表明纳格尔算法的转动。现在没有封闭的连接,尽管总体响应中有一个小滞后(当我使用winform,而不是异步时)。
我写了一些关于提示者如何神奇地"修复"的内容:http://blogs.telerik.com/fiddler/posts/13-02-28/help!-fiddler-fixes-my-app-
您遇到的问题实际上是.NET框架本身中的错误。HTTP的规则使得服务器在发送第一个响应后的任何时间都可以关闭守护连接(例如,即使客户端请求的keepalive行为,也不需要接受连接的其他请求)。
。 .NET有一个错误,如果在响应完成后将关闭连接,则该错误期望服务器将包含Connection: close
响应标头。如果服务器在没有Connection: Close
标头的情况下关闭连接(每RFC2616完全有效),则.NET在尝试在连接上发送下一个请求时会遇到封闭的连接,并且会引发此异常。.net 应该做的是默默地创建一个新连接,并在该新连接上重新集中请求。
提琴手解决此问题,因为它不在乎服务器是否关闭连接,并且可以使与客户端的连接保持活力。当客户端发送其第二个请求时,Fiddler试图重复使用其与服务器的连接,注意它已关闭并默默地创建了一个新连接。
您可以通过:
在代码中缓解此问题- 禁用请求(这损害性能)
- 捕获例外并自动重试
- 更改服务器以保持连接寿命更长
方法#3仅在控制服务器时才有效,并且由于客户端可能在使用后关闭连接的网关/代理后面,因此您可能还应使用方法#2。
一个建议和一个问题:1)如果您真的想查看安装Wireshark的情况。它将向您显示要发送/接收的内容。这将使与提琴手进行比较。我想您缺少一个标题,例如request.contenttype =" ....",但是只有Wireshark会向您展示哪个(通过您的工作替代方案发送,而不是由您的httpwebrequest发送)。
。2)您是在http响应内容内部遇到错误,还是一个例外,如果是例外,它是在捕获中捕获的,还是在请求期间发生,在您的try语句之前发生?
提琴手充当互联网代理。如果您的代码在运行时可以使用(也许也可以来自浏览器),那么您的代理设置可能会有问题。