底层连接被关闭:发生了意外错误。

3
我有一个非常简单的服务,它调用一个URL并捕获由该服务编写的状态;
// Service call used to determine availability
System.Net.WebClient client = new System.Net.WebClient();

// I need this one (sorry, cannot disclose the actual URL)
Console.WriteLine(client.DownloadString(myServiceURL + ";ping"));

// I added this for test purposes
Console.WriteLine(client.DownloadString("https://www.google.com"));

我的代码中的"myServiceURL"使用"DownloadString"方法时,会抛出错误"The underlying connection was closed: An unexpected error occurred",但是在这一行没有任何Fiddler记录。然而,当我使用"DownloadString"方法访问google.com时,代码能够正常运行并输出控制台信息。

为了解决这个问题,我尝试了其他建议,包括设置UseDefaultCredentials、Encoding选项、添加适当的请求头等,但都没有任何改善。

client.UseDefaultCredentials = true;
client.Encoding = Encoding.UTF8;

当我在浏览器中输入myServiceURL并打开时,它按预期工作并显示“OK”。
同一个服务的另一种方法已编写如下:
// Request
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(myServiceURL + ";login");

// Set the request configuration options
req.Method = "POST";
req.ContentType = "text/xml";
req.ContentLength = bytes.Length;
req.Timeout = -1;

// Call for the request stream
using (Stream os = req.GetRequestStream())
{
    os.Write(bytes, 0, bytes.Length);
}

// ....snip

// This line fails with the same error as before
WebResponse resp = req.GetResponse()

这一切都在运行 Windows 7 (64-bit) 电脑上,使用 .NET Framework 4.0;myServiceURL 上的服务是第三方服务,我无法控制。


你尝试过使用 req.Proxy = WebProxy.GetDefaultProxy(); 吗? - Amit Pore
刚刚尝试使用了GetDefaultProxy(已被弃用?),但没有任何改变。 - Sean
抱歉,那个问题是我的错。我猜你可以使用以下代码而不是 contentype:req as HttpWebRequest.Accept = "text/xml"; - Amit Pore
你可以参考Jon Skeet的回答,使用Wireshark来解决Web服务错误:“底层连接已关闭,发生了意外的错误”。http://stackoverflow.com/questions/4207428/webservice-error-the-underlying-connection-was-closed-an-unexpected-error-oc?rq=1 - Amit Pore
交换了ContentType和Accept...没有任何变化。 - Sean
已安装WireShark并过滤目标IP地址;它显示了一些“东西”,但由于不熟悉WireShark,我不太确定自己在看什么;我看到:SSL协议:长度194:客户端Hello -> 443 [ACK] Seq = 141 Ack = 1 Win = 64240 Len = 0 -> 443 [FIN,ACK] Seq = 141 Ack = 2 Win = 64240 Len = 0如果能得到一些指导,我可以提供更多来自WireShark的详细信息。 - Sean
2个回答

6
最终找到了问题的根源,虽然这个答案可能不适用于所有遇到同样问题的人;我建议关键在于我们可以从一些HTTPS网站中获取信息,但并非所有网站。通过Fiddler、WireShark和我们的防火墙结合追踪事件,我们发现了线索。

在Google Chrome中打开网站,并点击URL地址中的“https”锁形图标,查看“安全概述”,我们发现对于我们尝试的大多数网站,都列出了“有效证书”和“安全资源”的条目,但是此网站还列出了“安全TLS连接”的条目,WireShark确认握手(来自Chrome)正在使用TLS v1.2。

TLS v1.2似乎仅受.NET Framework 4.5(或更高版本)支持,因此需要Visual Studio 2012(或更高版本)。

我们目前正在运行.NET Framework 4.0和Visual Studio 2010。

下载了Visual Studio 2015 Community Edition,以测试在使用.NET Framework 4.5.2的项目中运行“相同”代码,结果直接奏效。


0
       //assuming this is set
        byte[] Data;
        string url = string.Format("{0};{1}" ,myServiceURL, "login");
        // Request
        HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(url);

        wreq.Method = "POST";
        wreq.Proxy = WebProxy.GetDefaultProxy();

        (wreq as HttpWebRequest).Accept = "text/xml";


        if (Data != null && Data.Length > 0)
        {
            wreq.ContentType = "application/x-www-form-urlencoded";
            System.IO.Stream request = wreq.GetRequestStream();
            request.Write(Data, 0, Data.Length);
            request.Close();
        }
        WebResponse wrsp = wreq.GetResponse();

我不太确定这段代码与我一直在使用的代码有什么显著的不同,但我已经尝试了这个...出现了相同的错误,我真的怀疑除了代码之外还有其他问题,因为对google.com的相同请求和一个简单的文本文件(上传到我的服务器)都按照我预期的方式工作。调查仍在继续。 - Sean
我明白,只是尝试一下。更改在contentType ""application/x-www-form-urlencoded"",请看这篇文章https://dev59.com/CG865IYBdhLWcg3wEKSZ - Amit Pore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接