Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# httpWebRequest(基础连接已关闭:连接意外关闭。)_C#_Httpwebrequest_Fiddler_Connectionexception - Fatal编程技术网

C# httpWebRequest(基础连接已关闭:连接意外关闭。)

C# httpWebRequest(基础连接已关闭:连接意外关闭。),c#,httpwebrequest,fiddler,connectionexception,C#,Httpwebrequest,Fiddler,Connectionexception,我正在开发一个C#应用程序,它记录来自Web服务器的数据。它向Web服务器发送以下post请求并等待响应 /// <summary> /// Function for obtaining testCgi data /// </summary> /// <param name="Parameters"></param> /// <returns></returns> priva

我正在开发一个C#应用程序,它记录来自Web服务器的数据。它向Web服务器发送以下post请求并等待响应

    /// <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;
    }
我试图调试错误,并且使用fiddler检查Firefox给出的post请求。令我惊讶的是,每当Fiddler出现时,我的程序都运行得很好。当我关闭小提琴手,我有同样的错误

我怀疑,由于Fiddler充当代理,它可能会更改某些设置。 我尝试过使用webclient,结果是一样的

当我尝试用python编写请求时,一切正常,没有问题。在CouCE中,我可以选择安装IrPython和包装特定的功能,但是我认为这种过度和缺乏优雅,所以我正在寻求一种更简洁的方法。我怀疑这只是一个设置调整

我尝试过修改,在我的情况下,它是无关紧要的

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的建议,我研究了延迟。 我找到了这篇文章 这意味着要改变Nagle算法。
现在没有关闭的连接,尽管总体响应有一个小的滞后(当我使用winforms时,而不是async)。

一个建议和一个问题: 1) 如果你真的想看看发生了什么,请安装Wireshark。它将准确地向您显示发送/接收的内容。这将使我们有可能与小提琴手进行比较。 我猜您缺少了一个标题,比如request.ContentType=“…”,但只有wireshark会显示哪个标题(通过您的工作备选方案发送,而不是通过您的HttpWebRequest发送)


2) 您是在http响应内容中得到错误,还是异常?如果是异常,是在您的捕获中捕获的,还是在请求过程中发生的,在您的try语句之前?

Fiddler充当Internet代理。如果您的代码在Fiddler运行时工作(也可能来自浏览器),那么您的代理设置可能有问题。

我在这里介绍了Fiddler如何“神奇地”修复问题:

您遇到的问题实际上是.NET框架本身的一个bug。HTTP的规则是,服务器可以在发送第一个响应后随时关闭KeepAlive连接(例如,即使客户端请求KeepAlive行为,它也不需要接受连接上的另一个请求)

.NET有一个错误,它希望服务器在响应完成后关闭连接时包含一个
连接:close
响应头。如果服务器在没有
连接:Close
头的情况下关闭连接(根据RFC2616完全有效),.NET在尝试发送连接上的下一个请求时将遇到关闭的连接,并将引发此异常。NET应该做的是以静默方式创建一个新连接,并在该新连接上重新发送请求

Fiddler解决了这个问题,因为它不关心服务器是否关闭了连接,并且保持与客户端的连接处于活动状态。当客户机发送第二个请求时,Fiddler尝试重用它与服务器的连接,注意到它已关闭,并以静默方式创建一个新连接

您可以通过以下方式在代码中缓解此问题:

  • 对请求禁用keepalive(这会影响性能)
  • 捕获异常并自动重试
  • 更改服务器以延长连接的活动时间

  • 方法#3仅在您控制服务器的情况下有效,并且由于客户端可能位于使用后关闭连接的网关/代理之后,您可能也应该使用方法#2。

    我已安装Wireshark,并且我已确认标头是相同的。:-(我对代码进行了如下修改,将整个请求封装在一个try-catch中(并添加了一个最大计数器),正如您所建议的那样,如果我尝试几次,最终会得到所需的结果。(我还添加了request.ServicePoint.Expect100Continue=false;)然而,成功之前的重试次数似乎是随机的。这正常吗?不幸的是,选项3对我来说不可用。选项1似乎可以缓解问题。因为在这个应用程序中,数据量对我来说是一个问题,您是否建议使用不同的方法(例如包装的ironPython函数)来获取数据,然后roceed与往常一样?你应该在禁用Keep Alive的情况下评测应用程序,并检查其影响;关键变量是延迟和请求数,而不是实际数据量。@ErikLaw由于我对Http调试相对较新,你能建议我进行一些简单的阅读吗?如果你想彻底了解Http,我会使用RFC2616和“HTTP:The definal Reference”(HTTP:The definal Reference),但两者都不是真正的“light”(轻松)。如果目标只是简单地了解更多关于延迟的信息,那么只需查看Fiddler中的流量,并查看Statistics(统计)选项卡,查看建立连接和发送请求所需的时间。
    WebResponse response = request.GetResponse();