C#HttpWebRequest底层连接已关闭:发送时发生意外错误

时间:2015-09-25 18:22:39

标签: c# httpwebrequest

我一直在谷歌搜索并尝试我能找到或想到的所有解决方案。我尝试加载的网站正在运行TLS1.2,我试图测试的其他几个网站也确保它不是TLS1.2问题。其他网站装得很好。

byte[] buffer = Encoding.ASCII.GetBytes(
    "mod=www&ssl=1&dest=account_settings.ws"
    + "&username=" + username.Replace(" ", "20%")
    + "&password=" + password.Replace(" ", "20%"));

ServicePointManager.MaxServicePointIdleTime = 1000;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

HttpWebRequest WebReq =
    (HttpWebRequest)WebRequest.Create(
        "https://secure.runescape.com/m=weblogin/login.ws");

WebReq.Method = "POST";
WebReq.KeepAlive = false;

WebReq.Referer =
    "https://secure.runescape.com/m=weblogin/loginform.ws"
    + "?mod=www&ssl=1&expired=0&dest=account_settings.ws";

WebReq.ContentType = "application/x-www-form-urlencoded";
WebReq.ContentLength = buffer.Length;
Stream PostData = WebReq.GetRequestStream();
PostData.Write(buffer, 0, buffer.Length);
PostData.Close();
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
Stream Answer = WebResp.GetResponseStream();
StreamReader _Answer = new StreamReader(Answer);
reply = _Answer.ReadToEnd();
curAccount++;
if (reply.Contains("Login Successful"))
{
     eturn true;
}
else
{
     eturn false;
}

无论我尝试什么,我都会一直得到异常

  

基础连接已关闭:发送时发生意外错误。

根据我发现的更多细节

  

身份验证失败,因为远程方已关闭传输流。

7 个答案:

答案 0 :(得分:80)

在.Net框架的4.0版本中,ServicePointManager.SecurityProtocol仅提供two options来设置:

  • Ssl3:安全套接字层(SSL)3.0安全协议。
  • Tls:传输层安全性(TLS)1.0安全协议

在框架的下一个版本中,SecurityProtocolType枚举器使用较新的Tls协议进行了扩展,因此如果您的应用程序可以使用4.5版本,您也可以使用:

  • Tls11:指定传输层安全性(TLS)1.1安全协议
  • Tls12:指定传输层安全性(TLS)1.2安全协议。

所以如果你在.Net 4.5上改变你的行

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

以便ServicePointManager创建支持Tls12连接的流。

请注意,枚举值可用作标志,因此您可以将多个协议与逻辑OR组合

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | 
                                       SecurityProtocolType.Tls11 |
                                       SecurityProtocolType.Tls12;

注意
尽量使用尽可能低的协议数量并使用当前的安全标准保持最新。 Ssll3不再被视为安全,Tls1.0 SecurityProtocolType.Tls的使用率正在下降。

答案 1 :(得分:13)

我遇到了这个例外,它也与ServicePointManager.SecurityProtocol有关。

对我来说,这是因为ServicePointManager.SecurityProtocol已设置为Tls | Tls11(因为某些网站的应用程序访问了破坏的TLS 1.2)以及访问仅限TLS 1.2的网站(使用{{进行了测试) 3}}),它失败了。

.NET 4.5及更高版本的选项是启用所有TLS版本:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                                     | SecurityProtocolType.Tls11
                                     | SecurityProtocolType.Tls12;

答案 2 :(得分:6)

对于.Net 4使用:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072;

答案 3 :(得分:1)

WebTestPlugIn代码

public class Protocols : WebTestPlugin
{

    public override void PreRequest(object sender, PreRequestEventArgs e)
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

    }

}

答案 4 :(得分:1)

您的项目支持.Net Framework 4.0和.Net Framework 4.5。 如果您有升级问题

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

代替可以使用;

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

答案 5 :(得分:0)

我遇到了类似的问题,以下内容帮助我解决了这个问题。我只是将这一行粘贴到身份验证代码上方,并且有效

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

答案 6 :(得分:0)

从IE启用TL 1.2并添加以下内容

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;