C# HttpWebRequest The underlying connection was closed: An unexpected error occurred on a send
Asked Answered
B

7

38

I've been Googling and trying all the solutions I could find or think of myself. The site I'm trying to load is running TLS1.2 as is a few other sites I tried to test with to make sure it wasn't a TLS1.2 issue. The other sites loaded fine.

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;
}

No matter what I try I keep getting the exception

The underlying connection was closed: An unexpected error occurred on a send.

Under more details I found

Authentication failed because the remote party has closed the transport stream.

Bedad answered 25/9, 2015 at 18:22 Comment(0)
L
115

In 4.0 version of the .Net framework the ServicePointManager.SecurityProtocol only offered two options to set:

  • Ssl3: Secure Socket Layer (SSL) 3.0 security protocol.
  • Tls: Transport Layer Security (TLS) 1.0 security protocol

In the next release of the framework the SecurityProtocolType enumerator got extended with the newer Tls protocols, so if your application can use th 4.5 version you can also use:

  • Tls11: Specifies the Transport Layer Security (TLS) 1.1 security protocol
  • Tls12: Specifies the Transport Layer Security (TLS) 1.2 security protocol.

So if you are on .Net 4.5 change your line

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

to

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

so that the ServicePointManager will create streams that support Tls12 connections.

Do notice that the enumeration values can be used as flags so you can combine multiple protocols with a logical OR

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

Note
Try to keep the number of protocols you support as low as possible and up-to-date with today security standards. Ssll3 is no longer deemed secure and the usage of Tls1.0 SecurityProtocolType.Tls is in decline.

Lobe answered 25/9, 2015 at 19:39 Comment(1)
You probably want Tls | Tls11 | Tls12 in most cases.Immerse
I
17

I experienced this exception, and it was also related to ServicePointManager.SecurityProtocol.

For me, this was because ServicePointManager.SecurityProtocol had been set to Tls | Tls11 (because of certain websites the application visits with broken TLS 1.2) and upon visiting a TLS 1.2-only website (tested with SSLLabs' SSL Report), it failed.

An option for .NET 4.5 and higher is to enable all TLS versions:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                                     | SecurityProtocolType.Tls11
                                     | SecurityProtocolType.Tls12;
Immerse answered 17/10, 2016 at 6:57 Comment(0)
B
15

For .Net 4 use:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)768 | (SecurityProtocolType)3072;
Bergen answered 10/9, 2017 at 20:41 Comment(2)
Generally, don't use magic constants.Immerse
Constants are defined here: learn.microsoft.com/en-us/dotnet/api/…Orangeman
I
3

Your project supports .Net Framework 4.0 and .Net Framework 4.5. If you have upgrade issues

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

instead of can use;

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
Instrumentalist answered 2/1, 2020 at 11:53 Comment(0)
L
2

I had similar issue and the below line helped me solving the issue.Thanks to rene. I just pasted this line above the authentication code and it worked

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Lamontlamontagne answered 17/12, 2019 at 6:2 Comment(0)
H
1

Code for WebTestPlugIn

public class Protocols : WebTestPlugin
{

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

    }

}
Hoang answered 6/3, 2018 at 9:31 Comment(0)
B
1

Enable TLs 1.2 from IE and add the following

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Brassware answered 23/11, 2020 at 7:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.